Double Pointer - The first common node of two linked lists, Ring Chain List II, and two numbers for s, flipping word order

Sword Finger Offer 18.Delete a node from a list of chains

Given the head pointer of a one-way chain table and the value of a node to be deleted, define a function to delete the node.
Returns the head node of the deleted list. The Title guarantees that the values of the nodes in the list are different from each other.

pre and node refer to the previous node and the node to be judged respectively

class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        if head.val == val: return head.next
        pre, node = head, head.next
        while node:
            if node.val==val:
                pre.next = node.next
                node = pre.next
            else:
                pre = node
                node = node.next
        return head

Swordfinger Offer 22.The last k th node in the list of chains

Third to last, k=3
- - - - - - - None
- - - - k - - None
i. - - j. - - - None

class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        i = j = head
        for _ in range(k):
            if j:
                j = j.next
            else: return i # k is longer than the list of chains
        while j:
            i=i.next
            j=j.next
        return i

Swordfinger Offer 25.Merge two sorted chains

Enter two incrementally ordered chains, merge the two chains, and leave the nodes in the new chains in incremental order.
My criteria for judgment start with l1 or l2. I generate a header node by referencing the answer, and no extra judgment is required.

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not l1: return l2
        if not l2: return l1
        if l1.val <= l2.val:
            head = l1
            l1 = l1.next
        else:
            head = l2
            l2 = l2.next
        cur = head
        while l1 and l2:
            if l1.val < l2.val:
                cur.next, l1 = l1, l1.next
            else:
                cur.next, l2 = l2, l2.next
            cur = cur.next
        cur.next = l1 if l1 else l2
        return head

Reference Answer

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        cur = dum = ListNode(0)
        while l1 and l2:
            if l1.val < l2.val:
                cur.next, l1 = l1, l1.next
            else:
                cur.next, l2 = l2, l2.next
            cur = cur.next
        cur.next = l1 if l1 else l2
        return dum.next

Swordfinger Offer 52.First common node of two linked lists

Unexpected, it involves clever mathematical calculations, similar to the ring entrance found below.

Explanation: Here the last None is also considered a node

The two lists are L1+C, L2+C respectively. C is the length of the public part. According to the landowner's practice: the first person takes L1+C step, then returns to the starting point of the second person to take L2 step; the second person takes L2+C step, then returns to the starting point of the first person to take L1 step. When both people walk L1+L2+C, they meet.

In disjoint cases, set the A-list length to be a B-list length, b-last a+b = b+a, so it must go to None together. It can be understood that both chains end up pointing to the same null (None) node, instead of the special case of disjoint. Very clever.

Instead of
node1 = node1.next if node1.next else headB

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        node1, node2 = headA, headB

        while node1 != node2:
            node1 = node1.next if node1 else headB # When node1 goes to the None node of A, it goes to B next
            node2 = node2.next if node2 else headA
        # When A and B are equal in length, the result is known the first time
        return node1

leetcode142.Ring Chain Table II

https://leetcode-cn.com/problems/linked-list-cycle-ii/
Given a list of chains, returns the first node at which the list begins to ring. If the list is not ring, returns null.

To represent rings in a given chain table, we use the integer pos to represent the position where the end of the chain is connected to the chain table (the index starts at 0). If pos is -1, there are no rings in the chain table. Note that pos is only used to identify rings and is not passed as a parameter to the function.




Summary:
f=2s (2 steps per fast pointer, exactly twice the distance)
f = s + nb (when we met, we just made a lot of n laps)
Launch 1.First encounter, slow = nb
2.Walk from the head node to the entry ring: a + nb
3.And slow has already moved nb, so slow's next step a is the point of entry.
4.From 3, start distance entrance = first encounter location + a

How do you know that slow has just taken step a? Start with the head and walk with the slow pointer, and it happens to be step a when you meet

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast, slow = head, head
        while True:
            if not (fast and fast.next): return None
            fast, slow = fast.next.next, slow.next
            if fast == slow: break
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast

Sword Finger Offer 21.Adjust the order of arrays so that odd numbers precede even numbers

Enter an integer array and implement a function to adjust the order of the numbers in the array so that all odd numbers are in the first half of the array and all even numbers are in the second half.

The x&1 bit operation is equivalent to the x% 2x%2 redundancy operation, that is, it can be used to determine the parity of numbers.

class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        i, j = 0, len(nums)-1
        while i<j: # Maybe it doesn't happen here i==j
            while i<j: # Can't equal, when i==j it ends
                if nums[i]%2==1: i+=1
                else: break
            while j>i:
                if nums[j]%2==0: j-=1
                else: break
            if i!=j:
                tmp = nums[i] 
                nums[i] = nums[j]
                nums[j] = tmp

        return nums
        
class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            while i < j and nums[i] & 1 == 1: i += 1
            while i < j and nums[j] & 1 == 0: j -= 1
            nums[i], nums[j] = nums[j], nums[i]
        return nums

Swordfinger Offer 57.And two numbers for s

Enter an incrementally ordered array and a number s, and look for two numbers in the array so that their sum is exactly s. If the sum of more than one number equals s s s, then output any pair.

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            s = nums[i] + nums[j]
            if s > target: j -= 1
            elif s < target: i += 1
            else: return nums[i], nums[j]
        return []

Swordfinger Offer 58 - I. Flip word order

Enter an English sentence and flip the order of the words in the sentence, but the order of the characters within the word does not change. For simplicity, punctuation is handled as normal letters. For example, enter the string "I am a student." "then output" student. a am I."

There are two details to deal with

The difference between split() and split('') in python

Method 1:
Using the built-in functions of String Split and List Reverse (not recommended for interviews), string flip requirements for this topic can be easily implemented.

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip() # Remove first and last spaces
        strs = s.split() # Split String
        strs.reverse() # Flip Word List # [: -1] is also in reverse order
        return ' '.join(strs) # Stitch into strings and return

Method 2: Double pointer, in words, to find each word as a list element

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip() # Remove first and last spaces
        i = j = len(s) - 1
        res = []
        while i >= 0:
            while i >= 0 and s[i] != ' ': i -= 1 # Search for first space
            res.append(s[i + 1: j + 1]) # Add Word
            while s[i] == ' ': i -= 1 # Skip space between words # i=-1 is actually the last
            j = i # j Final character pointing to the next word
        return ' '.join(res) # Stitch and return

Tags: Algorithm linked list

Posted on Fri, 08 Oct 2021 12:23:15 -0400 by betman_kizo