【每日刷题】链表-随想录2、3、LC160、LC141、142、21

1. 移除链表元素-随想录2.

虚拟头节点。

2. 反转链表-随想录3.

3. LC160、相交链表

题目链接

  1. 移到剩余长度相等时,再开始比较节点值。

在这里插入图片描述
2. 默认A比B长,移动A的指针到B开始的地方。如果遍历出来的长度是B比A长,那么交换A与B。
3. 一旦比较到节点相同,则一定是相交了,不会出现两者相交几个节点之后又岔开的情况,因为节点的next只有一个,所以不可能有一个节点后跟两个next,两者再次岔开。

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = 0;
        int lenB = 0;

        //求A长度
        ListNode curA = headA;
        while(curA != null){
            lenA++;
            curA = curA.next;
        }

        //求B长度
        ListNode curB = headB;
        while(curB != null){
            lenB++;
            curB = curB.next;
        }

        //默认A长度大于B,若不是,交换AB
        if (lenB > lenA){
            int temp = lenA;
            lenA = lenB;
            lenB = temp;

            ListNode tempN = headA;
            headA = headB;
            headB = tempN;
        }
         
        //让A从跟B一样长度的地方开始
        int diff = lenA - lenB;
        curA = headA;
        curB = headB;
        while (diff > 0){
            curA = curA.next;
            diff--;
        }

        //A剩下的长度和B一样长了,开始逐个遍历并比较节点
        while(curA != null){
            if (curA == curB){
                return curA;
            }else{
                curA = curA.next;
                curB = curB.next;
            }
        }
        return null;
    }
}

4. LC141 环形链表

题目链接
快慢指针,快指针一次比慢指针多移动一格。
如果快慢指针相遇,必有环。
注意:while条件:fast也要限制!=null,如果fast=null的话,就没有fast.next了

代码

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        while (slow != null && fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast){
                return true;
            }
        }
        return false;
    }
}

5. LC142 环形链表2

题目链接

和上题的区别是,这题要返回环形入口。
注意区分:相遇节点入口节点
在这里插入图片描述
表达式说明了:一个指针从头节点出发,一个指针从相遇节点出发,则两个指针必在入口处碰面。
已知头节点和相遇节点,则题目迎刃而解。

所以解题顺序就是:先找到相遇节点,再找到入口节点。

代码

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow = head;
        ListNode fast = head;
        ListNode meet = null;
        while(slow != null && fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if (slow == fast){
                meet = slow;
                break;
            }
        }
        if (meet == null){
            return null;
        }
        slow = head;
        fast = meet;
        while (slow != fast){
            len++;
            slow = slow.next;
            fast = fast.next;
        }
        return slow;
    }
}

6. LC21、合并两个有序链表

题目链接

递归做也可以。
注意这种解法不要忘记==null情况下,让dummy=dummy.next。因为continue后就直接跳出当前循环了,没办法执行循环里最后一句。

代码

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode dummy = new ListNode(-1);
        ListNode fix = dummy;
        ListNode node1 = list1;
        ListNode node2 = list2;
        while (node1 != null || node2 != null){
            if (node1 == null){
                dummy.next = node2;
                node2 = node2.next;
                dummy = dummy.next;
                continue;
            }
            if (node2 == null){
                dummy.next = node1;
                node1 = node1.next;
                dummy = dummy.next;
                continue;
            }
            if (node1.val > node2.val){
                dummy.next = node2;
                node2 = node2.next;
            }else{
                dummy.next = node1;
                node1 = node1.next;
            }
            dummy = dummy.next;
        }
        return fix.next;
    }
}

另一种简洁的:while循环条件不一样。
当有一方为null时,不再循环,cur.next直接为另一方的节点,后续也不用再while遍历,因为另一方的节点的后面连的都是这一方的节点。

private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode sentry = new ListNode(-1);
        ListNode curr = sentry;

        while(l1 != null && l2 != null) {
            if(l1.val < l2.val) {
                curr.next = l1;
                l1 = l1.next;
            } else {
                curr.next = l2;
                l2 = l2.next;
            }

            curr = curr.next;
        }

        if (l1 != null){
            curr.next = l1;
        }
        if (l2 != null){
            curr.next = l2;
        }
        return sentry.next;
    }
  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值