(Java)LeetCode-25. Reverse Nodes in k-Group

本文介绍了一种高效的链表翻转算法,通过每K个节点一组进行翻转操作,实现了链表的有效修改,同时保持了较低的空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

You may not alter the values in the nodes, only nodes itself may be changed.

Only constant memory is allowed.

For example,
Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5


这道题是反转每k的节点的子链,末尾不足k个的不反转。首先我的想法是每k个节点进栈,然后按照出栈的顺序连接起来,则自然反转,最后不足k个节点,就直接返回首节点。

代码方面也参照了上一题的迭代方法,很简洁。


public ListNode reverseKGroup(ListNode head, int k) {
        Stack<ListNode> st = new Stack<ListNode>();
        ListNode temp = head;
        for(int i = 0; i < k ; i++){
        	if(head != null){
        		st.push(head);
        	}else{
        		return temp;
        	}
        	head = head.next;
        }
        
        ListNode first = st.pop();
        ListNode res = first;
        for(int i = 0; i<k-1; i++){
        	first.next = st.pop();
        	first = first.next;
        }
        first.next = reverseKGroup(head,k);
		return res;
    }


但是呢,用stack一方面速度较慢,另一方面万一内存溢出就不好玩了,所以我下面采用了另一种方法来反转。其实链表的反转是一个经典题目,这个过程之前也看到过,这里只是有一点点的不一样,即不是反转全部链表,而是一部分一部分的反转。就单部分反转来说,思路是一样的。


思路如下:每次都将原第一个结点之后的那个结点放在头节点的后面,下图是原始的单链表。单链表反转示例图片

  为了反转这个单链表,我们先让头结点的next域指向结点2,再让结点1的next域指向结点3,最后将结点2的next域指向结点1,就完成了第一次交换,顺序就变成了Header-结点2-结点1-结点3-结点4-NULL,然后进行相同的交换将结点3移动到结点2的前面,然后再将结点4移动到结点3的前面就完成了反转。

写代码的时候呢,用root.next指向子链表里的第一个节点,head为第一个节点,反转一次即变成第二个几点,从而保证他后面的节点就是下一个将被放到前面的节点。用一个临时节点保存root后面的节点,被交换到前面的节点将指向这个临时节点。代码如下~运行时间缩短到1ms


public ListNode reverseKGroup(ListNode head, int k) {
		ListNode root = new ListNode(-1);
		root.next = head;
		ListNode res = root;
		ListNode temp = head;
		int i = 0;
		while(temp != null){
			i++;
			temp = temp.next;
		}
		while(i >= k){
			for(int j = 0 ; j < k-1; j++){
				ListNode node = root.next;
				root.next = head.next;
				head.next = root.next.next;
				root.next.next = node;
			}
			root = head;
			head = head.next;
			i-=k;
		}
		return res.next;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值