代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交

第一题

 19.Remove Nth Node From End of List

代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交_第1张图片

 第一次根据题意自己写代码:

//这个编码是错误的!!!
class Solution{
    public ListNode removeNthFromEnd(ListNode head, int n){
        ListNode dummy = new ListNode(0); //因为要输出完整的链表,所以最好定义dummy_node
        dummy.next = head;
        
        ListNode fast = head;
        ListNode slow = head;
        while(n > 0){
            fast = fast.next;
            n--;
        }
        while(fast.next != null){
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = fast;
        return dummy.next;
    }
}
错误地方在于当输入等于[1],n = 1;返回的是[1],而不是[0].


那要如何修改呢,请看一下修改之后的代码

//该代码则是正确的
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode slow = head; //应该从虚拟结点开始,不然导致第二个循环体条件出现问题(忽然不一定了)
        ListNode fast = head;
        while (n > 0){
            fast = fast.next;
            n--;
        }
        ListNode prev = dummy; //之前写的是prev = null;此时prev.next就不存在
        while (fast != null){ 
            prev = slow;
            slow = slow.next;
            fast = fast.next;
            // System.out.println(fast.val); //当Example 2:不执行
        }
        prev.next = slow.next;  
        return dummy.next;
    }
}

最后再看看原始的代码:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode slow = dummy;
        ListNode fast = dummy;
        while (n > 0){
            fast = fast.next;
            n--;
        }
        ListNode prev = null;
        while (fast != null){ 
            prev = slow;
            slow = slow.next;
            fast = fast.next;
            // System.out.println(fast.val);
        }
        prev.next = slow.next;  
        return dummy.next;
    }
}

借鉴了别人的博客,还可以这样写:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode slow = dummy;
        ListNode fast = dummy;
        while (n > 0){
            fast = fast.next;
            n--;
        }
        while (fast.next != null){ 
            slow = slow.next;
            fast = fast.next;
        }
        slow.next = slow.next.next; //当slow.next = fast; 会在[1], n=1情况下报错
        return dummy.next;
    }
}

以上的三种正确的写法其实本质上是一样的,只是存在一些些许的不同,帮助理解节点与指针,也学习区分不同代码之间的细小差别,打开思路。

第二题

代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交_第2张图片

这道题的关键是从相同的位置的开始遍历,其次因为链表没有length()函数,所以求长度要先进行一次遍历,再让指针回到初始位置。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode cur1 = headA;
        ListNode cur2 = headB;
        int lenA = 0, lenB = 0;
        while (cur1 != null){  //计算链表长度
            lenA += 1;
            cur1 = cur1.next;
        }
        while (cur2 != null){
            lenB++;
            cur2 = cur2.next;
        }
        cur1 = headA; //让指针重新指向起始位置
        cur2 = headB;
        if(lenB > lenA){   //始终保持A的length >= B.length
            int tempLen = lenA;
            lenA = lenB;
            lenB = tempLen;
            ListNode tempNode = cur1;
            cur1 = cur2;
            cur2 = tempNode;
        }
        int gap = lenA - lenB;
        while(gap-- > 0){
            cur1 = cur1.next;
        }
        while(cur1 != null){
            if (cur1 == cur2){
                // System.out.println(cur1);
                return cur1;
            }
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return null;
    }
}

第三题

代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交_第3张图片

 可以用flag函数来完成,给走过的地方都打上标记,但我不知道Java要如何实现,先贴一个别人的代码,防止忘记!

代码随想录算法训练营Day4 | | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 , 面试题 02.07. 链表相交_第4张图片

你可能感兴趣的:(Java日常学习,链表,java,学习)