代码随想录训练营第四天LeetCode24两两交换链表的结点,LeetCode19.删除链表的倒数第N个节点,LeetCode160链表香蕉,LeetCode142环形链表

代码随想录训练营第四天|LeetCode24两两交换链表的结点,LeetCode19.删除链表的倒数第N个节点,LeetCode160链表香蕉,LeetCode142环形链表1,LeetCode142环形链表2

题目链接24两两交换链表的结点

思路:主要搞清楚三个问题,第一是两个结点交换时操作指针一定指向第一个结点的前一个结点,第二是遍历的终止条件是什么,第三是两个结点交换的实现逻辑。

代码如下:

 public ListNode swapPairs(ListNode head) {
      ListNode s = new ListNode(-1,head);//定义一个哨兵结点并指向头结点
        ListNode curr = s;//定义指针指向哨兵结点
        while(curr.next != null && curr.next.next != null){//奇数个和偶数个都适用且不能颠倒顺序
            ListNode temp = curr.next;//哨兵结点断开了所以得保存第一个结点的指针
            ListNode temp1 = curr.next.next.next;//第二个结点断开所以保存第三个结点的指针
            curr.next = curr.next.next;//第一次是哨兵结点指向第二个结点
            curr.next.next = temp;
            curr.next.next.next = temp1;
            curr = curr.next.next;
        }
        return s.next;
    }

题目链接19删除链表的倒数第N个结点

思路:删除倒数第n个结点前一定得找到其前一个结点,用双指针法快慢指针首先都指向哨兵结点,然后快指针先走n+1步,然后再快慢指针同时走,然后找到了删除。

代码如下:

 public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode s = new ListNode(-1,head);
        ListNode fast = s;
        ListNode slow = s;
     	//快指针先走n+1步
        for(int i = 0; i <= n; i++){
            fast = fast.next;
        }
     	//快慢指针同时走
        while(fast != null){
            fast = fast.next;
            slow = slow.next;
        }
        slow.next = slow.next.next;
        return s.next;
    }

题目链接160链表相交

思路:搞清楚链表相交的结点一定是操作指针都指向它并且是第一次,所以两个链表长度不一样的话遍历速度也有所不同,于是可以求出两个链表长度的差值,然后将两个链表尾部对齐,让两个链表从同一起始位置遍历即可。

代码如下:

  public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA, curB = headB;
        int lenA = 0, lenB = 0;
        while(curA != null){
            lenA++;
            curA = curA.next;
        }
        while(curB != null){
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;
       //规范链表A比链表B长,便于后续计算
        if(lenB > lenA){
            int tempLen = lenA;
            lenA = lenB;
            lenB = tempLen;
            ListNode tempNode = curA;
            curA = curB;
            curB = tempNode;
        }
        int sub = lenA - lenB;
      //让链表A跑到链表B的起始位置
        while(sub-- > 0){
            curA = curA.next;        
        }
        while(curA != null){
            if(curA == curB){
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return null;
        
    }

题目链接141环形链表1

思路:定义一个快指针和慢指针,如果有环的话,以不同速度前进的两个指针一定会相遇。当慢指针一次走一步,快指针一次走两步,当快指针能走到终点的话则不存在环,当快指针能追到慢指针的话则存在环。

代码如下:

 public boolean hasCycle(ListNode head) {
        ListNode fast = head, slow = head;
        while(fast != null && fast.next != null){//以防fast.next为空指针
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                return true;
            }
        }
        return false;
        
    }

题目链接142环形链表2

思路:承接上一题,从两个指针第一次相遇开始,慢指针回到起点,快指针保持原位不变,慢指针和快指针一次都走一步当再次相遇时,地点就是环的入口。

代码如下:

 public ListNode detectCycle(ListNode head) {
         ListNode fast = head, slow = head;
        while(fast != null && fast.next != null){//以防fast.next为空指针
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                slow = head;
                while(true){
                    if(slow == fast){//以防链表是首尾相连的大回环
                        return fast;
                    }
                    fast = fast.next;
                    slow = slow.next;
                }
            }
        }
        return null;
    }
  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值