为了账号安全,请及时绑定邮箱和手机立即绑定

每天AC系列(十二):K个一组翻转链表

标签:
Java 算法

1 题目

LeetCode第25题,每K个节点一组进行翻转,剩下不足K个的保留原状.

在这里插入图片描述

2 直接翻转

将链表分成三部分,已翻转,待翻转,未翻转三部分:

在这里插入图片描述

首先,用一个指针t表示要插入的位置的前驱,一边把head移动k遍,一边插入在t后面(下图假设k=3):

在这里插入图片描述

int i=0;
for(;i<k && head != null;++i)
{
    temp = head.next;
    head.next = t.next;
    t.next = head;
    head = temp;
}

直接插在t的后面,一轮循环之后,移动t与head.

在这里插入图片描述

t的新位置为未插入head之前的head的位置,因此在插入之前把head的位置保存下来,直接使t移动到该位置,head的位置为自然移动到的位置,不需改变。

ListNode nextTPosition = head;
ListNode temp;
int i=0;
for(;i<k && head != null;++i)
{
    temp = head.next;
   	head.next = t.next;
   	t.next = head;
   	head = temp;
}
if(i == k)
   	t = nextTPosition;

接着再翻转,到达7后,7不需要翻转,因为剩下的节点数不足:

在这里插入图片描述

这时就需要i发挥作用了,i表示已翻转的节点的值,因为只是一次遍历,每遍历k次便翻转k次,若i小于k,由于已经翻转了剩下的i个节点,因此需要再将这剩下的i个节点翻转一次:

if(i == k)
	t = nextTPosition;
else
{
    for(head = t.next,t.next=null;head!=null;)
    {
        temp = head.next;
        head.next = t.next;
        t.next = head;
        head = temp;
    }
    break;
}

对剩下的i个节点再次翻转时,不需要修改t的位置,使head指向t.next,再把t.next置为null,因为此时t为

4->7

若不把t.next置为null,在

head.next = t.next

这一步会使head.next指向错误的t.next,导致会在最后一个节点不断循环。
翻转最后的i个节点后,跳出循环,返回结果。

在这里插入图片描述

3 递归

递归的话思路也类似,遍历k次,翻转k个,若还有需要翻转的节点,递归翻转,若没有,翻转剩下的i个节点。

if(i == k)
    t.next = reverse(head,k);

大部分代码与循环相同就不贴了,最大的不同是这里,这里的t为原来未遍历前的head,因为改成递归后,不需要使用t作为移动的指针指示插入的位置,t.next就相当于翻转后的最后一个节点,把递归的结果插入到这个节点的后面。

在这里插入图片描述

4 使用额外空间–栈

因为题目规定只能使用常数的额外空间,因此应该只有这两种方法了,但是,如果允许使用额外的空间,可以使用栈优化直接翻转的算法。

因为出栈的次序正是翻转的顺序,每遍历k个节点就压栈k个节点,若剩余不足k个节点,把head连上dummy,若还有多余的节点或者刚好遍历完,把出栈的节点依次连上主链。

while(true)
{
	Stack<ListNode> s = new Stack<>();
	ListNode temp = head;
	int i=0;
	for(;i<k && head != null;++i)
	{
	    s.add(new ListNode(head.val));
	    head = head.next;
	}
	if(i == k)
	{
	    for(i=0;i<k;++i)
	    {
	        t.next = s.pop();
	        t = t.next;
	    }
	}
	else if(head == null)
	{
	    t.next = temp;
	    break;
	}
}

其中for循环为遍历压栈,i==k判断是否翻转链表。

5 源码

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
5
获赞与收藏
30

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消