Day04: LeetCode. Linked List: 24, 19, 160, 142

24. Swap Nodes in Pairs

Given the head of a singly linked list, swap every two adjacent nodes and return its head.
You cannot modify the values in the nodes — only rearrange the nodes themselves

How the Code Works (Key Technique)

  • Dummy Node: A dummy node is placed before the actual head to handle swaps at the beginning easily.
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){return head;}

        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode curr = dummyHead;

        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 dummyHead.next;
    }
}

19. Remove Nth Node From End of List

Given the head of a singly linked list, remove the nth node from the end of the list and return the updated head of the list.

How the Code Works (Key Technique)

  • Dummy Node: A dummy node is placed before the actual head to handle swaps at the beginning easily.
  • Two-Pointer: Use two pointers (fasterNode and slowerNode). Move fasterNode forward by n+1 steps to maintain a gap of n nodes between the two pointers.

Complexity

  • Time Complexity: O(n) — where n is the length of the linked list. The list is traversed once. (Brute force will need 2n)
  • Space Complexity: O(1) — only a constant amount of extra space is used (for pointers and the dummy node).
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;

        ListNode fasterNode = dummyHead, slowerNode = dummyHead;
        for(int i = 0; i < n+1; i++){
            fasterNode = fasterNode.next;
        }
        while(fasterNode != null){
            fasterNode = fasterNode.next;
            slowerNode = slowerNode.next;
        }

        slowerNode.next = slowerNode.next.next;

        return dummyHead.next;
    }
}

160. Intersection of Two Linked Lists

Given the heads of two singly-linked lists, determine whether they intersect (i.e. share a common tail node). If they do, return the first shared node; otherwise return null.

How the Code Works (Key Technique)

  • Measure Lengths
  • Align the Lists
  • Traverse in Tandem: Move both pointers forward one node at a time. At each step, check if currA == currB. If so, you’ve found the intersection and return it.
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode currA = headA;
        ListNode currB = headB;

        int lengthA = 0;
        int lengthB = 0;

        while(currA !=null){
            currA = currA.next;
            lengthA++;
        }
        while(currB !=null){
            currB = currB.next;
            lengthB++;
        }

        int diff = 0;
        int restN = 0;
        currA = headA;
        currB = headB;

        if(lengthA > lengthB){
            diff = lengthA - lengthB;
            for(int i=0; i<diff; i++){
                currA = currA.next;
            }
            restN = lengthB;
        }else{
            diff = lengthB - lengthA;
            for(int i=0; i<diff; i++){
                currB = currB.next;
            }
            restN = lengthA;
        }

        for(int i=0; i<restN; i++){
            if(currA == currB){
                return currA;
            }else{
                currA = currA.next;
                currB = currB.next;
            }
        }
        return null;


    }
}

142. Linked List Cycle II

Given the head of a singly linked list, determine whether it contains a cycle—and if so, return the node where the cycle begins; otherwise, return null.

How the Code Works (Key Technique)

  • Cycle Detection: Two pointerscurrSlow (moves one step at a time) and currFast (moves two steps at a time)—traverse the list. If there is no cycle, currFast or currFast.next will hit null and we return null. If they ever meet, a cycle exists.
  • Finding the Cycle’s Entry Point: 

    Once currSlow and currFast meet inside the cycle, initialize two pointers. index1 at the head of the list, index2 at the meeting point(currFast). Add both one step at a time. They will first coincide exactly at the start of the cycle. That meeting node is returned as the cycle’s entry.(this concept can be prove by math)

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode currFast = head;
        ListNode currSlow = head;

        while(currFast != null && currFast.next != null){
            currFast = currFast.next.next;
            currSlow = currSlow.next;
            if(currFast == currSlow){
                ListNode index1 = head;
                ListNode index2 = currFast;

                while(index1 != index2){
                    index1 = index1.next;
                    index2 = index2.next;
                }      
                return index1;  
            }
        }
        return null;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值