• 牛客网—链表的回文结构


    本次写的题目是链表的回文结构,为牛客网里面的题目,让我们来康康是如何解出这道题目的吧,各位尚没有思路的小伙伴可以跟随着博主的解题思路一步步来,感受一下😎

    🌱分析阶段 

    博主在看到本题的第一个想法是可不可以找出中间位置之后一一对比,如下图👇:

     在思考了之后其实可行性不高,那么就开始思考有没有什么技巧可以用到,或者之前写过的什么题目里面的方法可以用到这里,来变换一下链表。

    在思考过后,认为可以用到博主之前写过的翻转链表题目与快慢结点技巧😎

    具体操作分为三步:

    1. 找到中间结点
    2. 将后半部分链表翻转
    3. 对比是否相等

    如果有写过中间结点与翻转链表的基础的话,这题是十分容易解决的,若没有这方面基础,这里博主推荐先写LeetCode中的这两道题:翻转链表返回链表的中间结点。也可以直接看博主写的这两道题的解答😎LeetCode第206题—反转链表LeetCode第876题—链表的中间结点

    掌握了这两个技巧之后,我们就直接进入到代码部分吧😎


    🌱代码阶段

    代码阶段基本上与翻转链表与返回链表的中间结点的代码部分无异,于是先写出下面部分👇:

    1. public class PalindromeList {
    2. public boolean chkPalindrome(ListNode A) {
    3. if(A==null) return false;
    4. if(A.next==null) return false;
    5. ListNode slow = A.next;
    6. ListNode fast = A.next.next;
    7. while(fast!=null&&fast.next!=null){ //当退出的时候cur就为中间结点
    8. fast = fast.next.next;
    9. slow = slow.next;
    10. }
    11. //拿到中间结点之后,就是翻转链表
    12. ListNode cur = slow.next;
    13. ListNode nextNode = slow.next.next;
    14. while(nextNode!=null){
    15. cur.next = slow;
    16. slow = cur;
    17. cur = nextNode;
    18. nextNode = nextNode.next;
    19. }
    20. cur.next = slow;
    21. slow = cur;
    22. }
    23. }

    唯一需要注意的是剩下的对比阶段,我们先以单数链表为例,写出下面的代码:

    1. public class PalindromeList {
    2. public boolean chkPalindrome(ListNode A) {
    3. if(A==null) return false;
    4. if(A.next==null) return false;
    5. ListNode slow = A.next;
    6. ListNode fast = A.next.next;
    7. while(fast!=null&&fast.next!=null){ //当退出的时候cur就为中间结点
    8. fast = fast.next.next;
    9. slow = slow.next;
    10. }
    11. //拿到中间结点之后,就是翻转链表
    12. ListNode cur = slow.next;
    13. ListNode nextNode = slow.next.next;
    14. while(nextNode!=null){
    15. cur.next = slow;
    16. slow = cur;
    17. cur = nextNode;
    18. nextNode = nextNode.next;
    19. }
    20. cur.next = slow;
    21. slow = cur;
    22. //翻转完后就需要比对,此时的的slow是用来比对的,翻转后可以让slow一直往下走,对比
    23. ListNode newHead = A;
    24. while(A!=slow){
    25. if(A.val!=slow.val){
    26. return false;
    27. }
    28. A = A.next;
    29. slow = slow.next;
    30. }
    31. return true;
    32. }
    33. }

     这里忽略了双数链表的对比情况,如果按照目前代码运行,若碰到双数链表,该代码会进入死循环,所以我们需要在最后的while语句内部再加双数链表的判断👇:

    1. public class PalindromeList {
    2. public boolean chkPalindrome(ListNode A) {
    3. if(A==null) return false;
    4. if(A.next==null) return false;
    5. ListNode slow = A.next;
    6. ListNode fast = A.next.next;
    7. while(fast!=null&&fast.next!=null){ //当退出的时候cur就为中间结点
    8. fast = fast.next.next;
    9. slow = slow.next;
    10. }
    11. //拿到中间结点之后,就是翻转链表
    12. ListNode cur = slow.next;
    13. ListNode nextNode = slow.next.next;
    14. while(nextNode!=null){
    15. cur.next = slow;
    16. slow = cur;
    17. cur = nextNode;
    18. nextNode = nextNode.next;
    19. }
    20. cur.next = slow;
    21. slow = cur;
    22. //翻转完后就需要比对,此时的的slow是用来比对的,翻转后可以让slow一直往下走,对比
    23. ListNode newHead = A;
    24. while(A!=slow){
    25. if(A.val!=slow.val){
    26. return false;
    27. }
    28. if(A.next==slow){ //若A的下一个就是slow,相当于此时A与slow都是中间结点
    29. return true;
    30. }
    31. A = A.next;
    32. slow = slow.next;
    33. }
    34. return true;
    35. }
    36. }

    至此,全部代码才算完成,让我们来运行来逝逝吧😎

    nice😎✨


    加一句题外话:这道题目其实还有另外一直解法,该解法需要用到相关知识,这里卖个关子,之后博主写到栈相关知识的时候再来揭晓,有已经学到栈相关知识的小伙伴也可以自己先逝逝😎加油

  • 相关阅读:
    pixel2的root过程
    常见排序算法(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序)
    2022-08-18 mysql/stonedb-aggregate场景group by分析
    【Java】java | CacheManager | redisCacheManager
    自定义MVC的使用
    IDEA双击无效打不开
    TiDB 中的视图功能
    万圣节服装上亚马逊美国站CPC认证的注意事项
    C++ 入狱日记 002 —— C++ 指针详解
    乳制品行业如何通过APS智能排产进行生产管理的优化?
  • 原文地址:https://blog.csdn.net/Green_756/article/details/126320786