首页 > 试题广场 >

链表中的节点每k个一组翻转

[编程题]链表中的节点每k个一组翻转
  • 热度指数:252329 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
将给出的链表中的节点每 k 个一组翻转,返回翻转后的链表
如果链表中的节点数不是 k 的倍数,将最后剩下的节点保持原样
你不能更改节点中的值,只能更改节点本身。

数据范围: ,链表中每个元素都满足
要求空间复杂度 ,时间复杂度
例如:
给定的链表是
对于 , 你应该返回
对于 , 你应该返回

示例1

输入

{1,2,3,4,5},2

输出

{2,1,4,3,5}
示例2

输入

{},1

输出

{}

说明:本题目包含复杂数据结构ListNode,点此查看相关信息
public class Solution {
    public static ListNode reverseKGroup(ListNode head, int k) {
		if(head == null || head.next == null || k < 2) return head;
		ListNode dummy = new ListNode(0);
		dummy.next = head;
		ListNode pre = dummy, cur = head, temp;
		int len = 0;
		while (head != null) {
			len ++ ;
			head = head.next;
		}
		for (int i = 0; i < len / k; i ++ ) {
			for (int j = 1; j < k; j ++ ) {
				temp = cur.next;
				cur.next = temp.next;
				temp.next = pre.next;
				pre.next = temp;
			}
			pre = cur;
			cur = cur.next;
		}
		return dummy.next;
	}
}

发表于 2016-11-17 23:53:43 回复(27)
import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        ListNode end = head;
        for (int i = 0; i < k; i++) {//找到翻转部分尾节点的下一个节点
            if (end == null) {
                return head;
            }
            end = end.next;
        }
        ListNode pre = null, cur = head;
        while(cur != end) {
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        head.next = reverseKGroup(end, k);//尾节点指向下一个翻转的头节点
        return pre;
    }
}

发表于 2021-08-08 17:44:54 回复(0)
class Solution {
public:
    /// 参考翻转pairs,翻转x~x+(k-1)之间的节点, x->next = reverseKGroup(x+k,k)
    ListNode* reverse(ListNode *first,ListNode *last)
    {
        ListNode *pre = nullptr;
        while(first!=last)
        {
            ListNode *temp = first->next;
            first->next = pre;
            pre = first;
            first = temp;
        }
        return pre;
    }
    ListNode *reverseKGroup(ListNode *head, int k) 
    {
        if(!head)
            return nullptr;
        ListNode *node = head;
        for(int i=0;i<k;i++)
        {
            if(!node)
                return head;
            node = node->next;
        }
        ListNode *newHead = reverse(head,node);
        head->next = reverseKGroup(node,k);
        return newHead;
    }
};

发表于 2017-07-14 21:47:26 回复(3)
class Solution:
    def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
        #递归
        cur = head
        count = 0
        while cur and count!= k:
            cur = cur.next
            count += 1
        if count == k:
            cur = self.reverseKGroup(cur, k)
            while count:
                tmp = head.next
                head.next = cur
                cur = head
                head = tmp
                count -= 1
            head = cur   
        return head

发表于 2021-12-09 22:28:41 回复(0)
public class Solution {
    public ListNode reverseKGroup (ListNode head, int k) {
        ListNode prev = null,curr = head;
        int times = k;
        while (times-- > 0){
            if(curr == null){
                return restore(prev);
            }

            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }

        head.next = reverseKGroup(curr, k);
        return prev;
    }

    private ListNode restore(ListNode head){    //不足k个时再反转还原
        ListNode prev = null,curr = head;
        while (curr != null){
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        }
        return prev;
    }
}

发表于 2021-03-19 16:09:07 回复(0)
class Solution {
public:
    ListNode* reverse(ListNode* node, int size, int k) {
        if (!node) return nullptr;
        if (size < k) return node;
        ListNode* end = node;
        ListNode* prev = node;
        ListNode* p = node->next;
        ListNode* next = nullptr;
        for (int i = 1; i < k; i++) {
            next = p->next;
            p->next = prev;
            prev = p;
            p = next;
        }
        end->next = reverse(next, size - k, k);
        return prev;
    }
    
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        if (k == 1) return head;
        int size = 0;
        ListNode* p = head;
        while (p != nullptr) {
            size++;
            p = p->next;
        }
        return reverse(head, size, k);
    }
};


编辑于 2021-01-02 11:57:06 回复(0)
C32头像 C32
//明显递归解决,翻转第一组之后,以第二组的开头为头节点,继续翻转,知道转翻到最后,返回。
public ListNode reverseKGroup(ListNode head, int k) {
       		 	   if(head==null||head.next==null)
			    	   return head;
			     	ListNode h=new ListNode(0);
			     	h.next=head;
			       	ListNode next=null,tmp=head,cur=head;
			       	for(int i=1;i<k;i++){
	                    cur=cur.next;
	                    if(cur==null)
	                        return head;
	                }
			       	next=cur.next;
			       	while(head.next!=next){
			       		tmp=head.next;
			       		head.next=tmp.next;
			       		tmp.next=h.next;
			       		h.next=tmp;
			       	}
			       	head.next=reverseKGroup(next,k);
			       	return h.next;
    }

发表于 2017-04-28 10:52:19 回复(1)
public ListNode reverseKGroup (ListNode head, int k) {
        ListNode tail=head;//tail为分组界限
        for(int i=0;i<k;i++){   //如果不足k个
            if(tail==null) return head;
            tail=tail.next;
        }
        //如果足k个,反转链表
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=tail){//因为下一段的头是tail
            ListNode tmp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=tmp;
        }
        head.next=reverseKGroup(tail,k);
        return pre;
    }

发表于 2023-07-19 09:41:24 回复(2)
来个最好理解的版本,就按照范围反转的模板来吧。
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        // write code here
        if (!head) return head;
        ListNode* p = head;
        int len = 0;
        while(p) {
            p = p->next;
            len++;
        }

        ListNode* newHead = head;
        for (int i = 0; i + k <= len; i += k) {
            newHead = reverseRange(newHead, i , i + k - 1);
        }

        return newHead;
    }

    ListNode* reverseRange(ListNode* head, int begin, int end) {
        if (begin == end) return head;
        ListNode du(-1);
        du.next = head;

        ListNode* pre = &du;
        ListNode* cur = head;
        ListNode* nxt = nullptr;
        int range = end - begin;
        int k = begin;
        while (k-- > 0) {
            pre = pre->next;
            cur = cur->next;
        }

        while (range--) {
            nxt = cur->next;
            cur->next = nxt->next;
            nxt->next = pre->next;
            pre->next = nxt;
        }

        return du.next;
    }
};


发表于 2023-05-12 00:00:06 回复(0)
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* reverseKGroup(ListNode* head, int k) {
        // 时间复杂度O(N),空间复杂度O(1)
        ListNode *dummy = new ListNode(-1);
        dummy->next = head;
        ListNode *pre = dummy, *cur = head, *tmp;
        while (true) {
            // 判断能否反转
            tmp = cur;
            for (int i = 0; i < k; ++i) {
                if (tmp) tmp = tmp->next;
                else return dummy->next;  // 节点已到空,不能反转,直接返回头节点
            }
            // 开始反转
            for (int i = 1; i < k; ++i) {
                tmp = cur->next;
                cur->next = tmp->next;
                tmp->next = pre->next;
                pre->next = tmp;
            }
            pre = cur;
            cur = cur->next;
        }
        return nullptr;
    }
};

发表于 2022-09-28 17:36:01 回复(0)
public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        ListNode res = new ListNode(-1);
        res.next = head;
        ListNode pre = res,cur = head;
        int length = 0;
        //获取链表的长度
        while (head != null) {
            length ++;
            head = head.next;
        }
        //需要分多少组
        int count = length / k;
        //需要翻转多少个链表
        while (count > 0) {
            //反转链表
            for (int j = 1; j < k; j++) {
                ListNode temp = cur.next;
                cur.next = temp.next;
                temp.next = pre.next;
                pre.next = temp;
            }
            count --;
            //翻转链表,当count已经为0,没必要再找一下节点,防止找下一个节点越界
            if (count > 0) {
                //cur节点刚好是链表翻转后的最后一个节点
                pre = cur;
                //cur.next是下一个需要翻转的起始节点
                cur = cur.next;
            }
        }
        return res.next;
    }

发表于 2022-09-21 17:51:51 回复(0)
/*
 * function ListNode(x){
 *   this.val = x;
 *   this.next = null;
 * }
 */

/**
  * 
  * @param head ListNode类 
  * @param k int整型 
  * @return ListNode类
  */
function reverseKGroup( head ,  k ) {
    // write code here
    let headNode = head
    //当k超过节点数时,直接返回
    for(let i=0;i<k;i++){
        if(headNode == null){
            return head
        }
        headNode = headNode.next
    }
    
    //对k个节点进行逆转(进行k-1此指向转换)
    let cur = head.next
    let pre = head
    for(let i=1;i<k;i++){
        let tmp = cur.next
        cur.next = pre
        pre = cur 
        cur = tmp       
    }
    //递归对下一组k个进行逆转,且每次都是把head指向下一组
    head.next = reverseKGroup(cur,k)
    //返回每一组逆序后实际的头节点(就是当前pre指向的,即每组第k个元素)
    return pre
}
module.exports = {
    reverseKGroup : reverseKGroup
};

发表于 2022-04-03 17:57:16 回复(1)
import java.util.*;

public class Main {
    static class ListNode{
        int val;
        ListNode next;
        ListNode(int val){
            this.val = val;
        }
    }
        // 这里全是输入处理
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while(in.hasNext()){
            String str = in.nextLine();
            int k = in.nextInt();
            ListNode head = new ListNode(-1);
            ListNode p = head;
            String[] strArray = str.split(" ");
            for(int i = 0; i < strArray.length - 1; i++){
                p.next = new ListNode(Integer.parseInt(strArray[i]));
                p = p.next;
            }
            head = reverseK(head.next, k);
            printList(head);
        }
    }
        // 输出处理
    private static void printList(ListNode head) {
        while(head != null){
            System.out.print(head.val);
            if(head.next != null){
                System.out.print("->");
            }
            head = head.next;
        }
    }
        // 核心程序
    private static ListNode reverseK(ListNode head, int k) {
        if(k == 1 || head == null || head.next == null){
            return head;
        }
        ListNode a = head, b = head;
        for(int i = 0; i < k; i++){
            if(b == null){
                return head;
            }
            b = b.next;
        }
        ListNode newHead = reverse(a, b);
        head.next = reverseK(b, k);
        return newHead;
    }

    private static ListNode reverse(ListNode a, ListNode b) {
        ListNode pre = null, cur = a;
        while(cur != b){
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }
        return  pre;
    }
}

发表于 2021-05-25 22:01:54 回复(0)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
   public ListNode reverseKGroup(ListNode head, int k) {
        if(head == null||head.next == null||k<=1)
            return head;
        
        ListNode node=head;
        
        ListNode helper=new ListNode(0);//创建一个辅助的头结点;
        helper.next=head;//当k> length of list时,返回原链表;
        ListNode lastgroup=helper;//记录上一组结点的尾结点;
        ListNode nextgroup=head;//辅助记录下一组结点的首结点;
        ListNode first=nextgroup;//记录下一组结点的首结点;
        int count=1;
        while(node!=null)
            {
            if(count<k)
                {
                count++;
                node=node.next;
            }else//count == k;
                {
                nextgroup=node.next;
                lastgroup.next=reverse(first,node);
                lastgroup=first;
                first.next=nextgroup;
                first=nextgroup;
                node=first;
                
                count=1;
            }
        }
        return helper.next;
        
    }
    //字符串反转通用方法;
    public ListNode reverse(ListNode head,ListNode tail)
        {
        ListNode pre=head;
        ListNode cur=head.next;
        ListNode ne=null;
        while(pre!=tail)
            {
            ne=cur.next;
            cur.next=pre;
            pre=cur;
            cur=ne;
        }
        head.next=null;
        head=pre;
        return head;
    }
}

发表于 2016-05-10 10:49:49 回复(0)
struct ListNode* reverseKGroup(struct ListNode* head, int k ) {
    // write code here
    struct ListNode *tail = head;
    //1、递归结束的点(k个为一组,不足k个直接返回head)
    for (int i = 0; i < k; i++){
        if (tail == NULL) {
            return head;
        }
        tail = tail->next;
    }

    struct ListNode *pre = NULL;
    struct ListNode *cur = head;
    struct ListNode *nex;
    //2、每一级的任务
    while (cur != tail) {
        nex = cur->next;
        cur->next = pre;
        pre = cur;
        cur = nex;
    }
    head->next = reverseKGroup(tail, k);
    //3、找到返回值
    return pre;
}

发表于 2023-03-19 14:50:13 回复(0)
def reverseKGroup(self , head: ListNode, k: int) -> ListNode:
    # write code here
    le = 0
    # 虚拟头结点
    hv = ListNode(0)
    hv.next = head
    t = hv
    # 计算长度
    while t.next is not None:
        le += 1
        t = t.next
    rev_time = le // k # 共需翻转rev_time次
    pre = hv
    cur = hv.next
    p,c = pre,cur # 暂存pre和cur
    for _ in range(rev_time):# 共需翻转rev_time次
        for _ in range(k):# 每次翻转k个元素
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        # 连接头尾结点并更新p和c
        p.next = pre
        p = c
        c.next = cur
        c = cur
    return hv.next

发表于 2023-02-22 15:52:58 回复(0)
java非递归
 public ListNode reverseKGroup (ListNode head, int k) {
        //虚拟头节点,返回first.next就是目标链表,也可以不用对链表是否为空进行分类处理
        ListNode first = new ListNode(0);
        first.next = head;
        //双指针
        ListNode start = head;
        ListNode pstart = first;
        while (true) {
            //判断后面是否有k个
            for (int i = 0; i < k; i++) {
                if (head != null) {
                    head = head.next;
                } else {
                    return first.next;
                }
            }

            //局部反转
            for (int i = 0; i < k-1; i++) {
                ListNode temp = start.next;
                start.next = start.next.next;
                temp.next = pstart.next;
                pstart.next = temp;
            }

            //为下一次反转做准备
            pstart = start;
            start = start.next;
        }
 }


发表于 2022-10-26 18:40:16 回复(0)
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    //翻转 a--b之间
    ListNode* reverselistnode(ListNode*a,ListNode*b){
        ListNode *pre= nullptr;
        while(a!=b){
            ListNode *temp =a->next;
            a->next =pre;
            pre =a;
            a =temp;
        }
        return pre;
    }
    
    
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head ==nullptr){
            return nullptr;
        }
        ListNode *a =head;
        ListNode *b =head;
        //a原地不动 b走k个  形成a---b区间
        for(int i=0;i<k;i++){
            if(b!=nullptr){
                b=b->next;
            }else{
                return head;
            }
        }
        
        //翻转ab区间 更新新的区间b--k
        ListNode *newhead =reverselistnode(a,b);
        a->next =reverseKGroup(b,k);
        return newhead;
        
        
    }
};

发表于 2022-05-11 20:24:04 回复(0)
public ListNode reverseKGroup(ListNode head, int k) {
        if (head == null || head.next == null)
            return head;
        //统计链表个数
        int n = 0;
        ListNode p = head;
        while (p != null) {
            n++;
            p = p.next;
        }
        //计算反转次数
        int t = n / k;
        if (t == 0)
            return head;
        ListNode dummy = new ListNode(-1);
        dummy.next = head;
        //记录上一次的尾节点
        ListNode lastTail = dummy;
        p = head;
        while (t-- > 0) {
            //记录本次反转的尾结点
            ListNode curTail = p;
            ListNode pre = null;
            for (int i = 0; i < k; i++) {
                ListNode next = p.next;
                p.next = pre;
                pre = p;
                p = next;
            }
            //完成后pre为反转后的头结点
            lastTail.next = pre;
            lastTail = curTail;
        }
        //处理最后一部分
        lastTail.next = p;
        return dummy.next;
    }

发表于 2022-04-30 22:21:20 回复(0)
import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        if(head==null) return null;
        ListNode a,b;
        a=b=head;
        for(int i=0;i<k;i++){
            if(b==null) return head;
            b=b.next;
        }
        ListNode newHead=reverse(a,b);
        a.next=reverseKGroup(b,k);
        return newHead;
    }
    public ListNode reverse(ListNode a,ListNode b){
        ListNode pre,cur,nxt;
        pre=null;cur=a;nxt=a;
        while(cur!=b){
            nxt=cur.next;
            cur.next=pre;
            pre=cur;
            cur=nxt;
        }
        return pre;
    }
}

发表于 2022-04-21 07:58:49 回复(0)

问题信息

难度:
518条回答 25327浏览

热门推荐

通过挑战的用户