链表算法题二,还原题目,用debug调试搞懂每一道题 (2)

现在当前节点【cur】已经指向【2】,那它的下个节点就是【1】,如下图所示。

链表算法题二,还原题目,用debug调试搞懂每一道题

经过上面的两步循环,成功的将指针进行了反转,剩下的节点循环也就如出一辙了。

链表算法题二,还原题目,用debug调试搞懂每一道题

当循环到最后节点【5】时,下个节点为null,此时结束while循环,而节点【5】也是指向了上一个节点【4】。

链表算法题二,还原题目,用debug调试搞懂每一道题

最后我们再看下运行结果。

链表算法题二,还原题目,用debug调试搞懂每一道题

二,回文链表

链表算法题二,还原题目,用debug调试搞懂每一道题

1.2.1 题目分析

如果做过字符串的算法题,里面有个回文字符串的题目。没错,它俩的意思是一样的。

看题目描述得知一个链表是不是回文链表,就是看链表就是看链表正读和反读是不是一样的。

假如说,我们拿到了后半部分链表,再将其反转。去和链表的前半部分比较,值相等就是回文链表了。

注意:

这种方式会破坏原链表的结构,为保证题目的一致性,最后再将链表再重新拼接

另外一种解题方式为:将整个链表节点遍历保存到数组中,而数组是有下标,并可以直接获取数组的大小,那么只需从数组的首尾去判断即可

反转链表上一道题我们已经分享了,现在重点是如何获取后半部分的链表。

我们再说说快慢指针的思想,通常我们定义2个指针,一个移动快,一个移动慢。详细的案例可以参考本人上一篇文章《开启算法之路,还原题目,用debug调试搞懂每一道题》,有一道关于快慢指针的题目。

链表算法题二,还原题目,用debug调试搞懂每一道题

定义慢指针每次移动1个节点,快指针每次移动2个节点,当然我们是需要保证快节点的下下个个节点不为空。

slow = slow.next; fast = fast.next.next;

链表算法题二,还原题目,用debug调试搞懂每一道题

其实快慢指针的思想就是,假设链表是一个回文链表,快指针比慢指针是多走一步,当快指针走完的时候,慢指针也就刚好走到该链表的一半。

上图中slow指针正好走到链表的一半,此时也就得到链表的后半部分了,即slow.next。

1.2.2 代码分析

老套路,先创建一个回文链表。

ListNode l1 = new ListNode(1); ListNode l2 = new ListNode(2); ListNode l3 = new ListNode(2); ListNode l4 = new ListNode(1); NodeFun nodeFun = new NodeFun(); nodeFun.add(l1); nodeFun.add(l2); nodeFun.add(l3); ListNode head = nodeFun.add(l4);

获取后半部分链表代码。

private ListNode endOfFirstHalf(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast.next != null && fast.next.next != null) { fast = fast.next.next; slow = slow.next; } return slow; }

反转链表的代码与上题目是一样的。

最后将两个链表进行判断是否是一样的。

// 判断是否回文 ListNode p1 = head; ListNode p2 = secondHalfStart; boolean flag = true; while (flag && p2 != null) { if (p1.val != p2.val) { flag = false; } p1 = p1.next; p2 = p2.next; } 1.2.3 debug调试

先获取链表的后半部分。

链表算法题二,还原题目,用debug调试搞懂每一道题

链表算法题二,还原题目,用debug调试搞懂每一道题

debug开始循环后,fast直接走到链表的第3个节点【2】

链表算法题二,还原题目,用debug调试搞懂每一道题

​ slow.next就是链表的后半部分,再将后半部分进行链表反转

最后我们也就得到如下2个链表。

链表算法题二,还原题目,用debug调试搞懂每一道题

最后将这2个链表进行比较是否相等,相等则是回文链表。

三,链表的中间节点

链表算法题二,还原题目,用debug调试搞懂每一道题

1.3.1 题目分析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwwfjs.html