Linked List Flashcards

1
Q
  1. Add Two Numbers
    You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Example:

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

A

Use two pointers. One pointer for each list.
Use dummy node is better.
while l1 or l2 or carrier
Keep maintain the sum and carry.
After both lists are empty. if still has a carrier, add a new node.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q
  1. Remove Nth Node From End of List
    Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:

Given n will always be valid.

Follow up:

Could you do this in one pass?

A

Use two pointer. Fast, slow. Fast is n+1 step faster than slow. Once the fast pointer meet the end. The slow pointer just bypass the next pointer. slow.next=slow.next.next

Use two loop. First loop let hte fast is n+1 step faster than slow. Second loop, both pointer go together. Stop when fast pointer meet the end.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q
  1. Merge Two Sorted Lists
    Merge two sorted linked lists and return it as a new sorted list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

A
Use two-pointer. One on l1. one on l2.
Let the smaller first node as l1.
Then compare two-pointer p1,p2. 
If p2 > p1.next: p1=p1.next
else:                  insert the p2. and let p2 go one step. p1 go one step.
Or use recursive is more concise(return a or b  will return the first one).
class Solution:
    def mergeTwoLists(self, a, b):
        if a and b:
            if a.val > b.val:
                a, b = b, a
            a.next = self.mergeTwoLists(a.next, b)
        return a or b
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q
  1. Merge k Sorted Lists
    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6
A

Use a list of pointers. And use a priority queue to save(node.val, node) track the smallest element and add the smallest list.
OR
Use DIvide and conquer. The naive thought is to merge two list k-1 times. But if using Divide and conquer, you can merge logk time.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
  1. Swap Nodes in Pairs
    Given a linked list, swap every two adjacent nodes and return its head.

You may not modify the values in the list’s nodes, only nodes itself may be changed.

Example:

Given 1->2->3->4, you should return the list as 2->1->4->3.

A

Use a dummy node. Start from the dummy node.
if cur.next and cur.next.next: then swap the next to nodes.
Then cur = cur.next.next

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q
  1. Rotate List
    Given a linked list, rotate the list to the right by k places, where k is non-negative.

Example 1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
rotate 1 steps to the right: 5->1->2->3->4->NULL
rotate 2 steps to the right: 4->5->1->2->3->NULL
Example 2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
rotate 1 steps to the right: 2->0->1->NULL
rotate 2 steps to the right: 1->2->0->NULL
rotate 3 steps to the right: 0->1->2->NULL
rotate 4 steps to the right: 2->0->1->NULL

A

Use two pointer. fast and slow. fast is k step faster than slow.
Two loops. First loop let fast pointer go k step.
second loop, both pointer go together untill the fast reach the end
while(fast.next)
Then fast.next = slow
dummy.next = slow.next
slow.next = None

Note: if k&raquo_space; len(lsit). It will be very slow. So we should calculate the length first. Then let k=k % len(list).

These processes above can be done with one pointer too. Just do the fast pointer job first then slow pointer later.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q
  1. Remove Duplicates from Sorted List II
    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

Return the linked list sorted as well.

Example 1:

Input: 1->2->3->3->4->4->5
Output: 1->2->5
Example 2:

Input: 1->1->1->2->3
Output: 2->3

A

Two pointers. fast and slow. If next node and next.next node is the different value. Then both pointers go one step. If they are the same. Then let the fast pointer keep going until met the different value. Then slow.next = fast

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q
  1. Remove Duplicates from Sorted List
    Given a sorted linked list, delete all duplicates such that each element appear only once.

Example 1:

Input: 1->1->2
Output: 1->2
Example 2:

Input: 1->1->2->3->3
Output: 1->2->3

A

Use one pointer. If cur.next.val == cur.val. Then cur.next = cur.next.next just skip it.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q
  1. Partition List
    Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

Example:

Input: head = 1->4->3->2->5->2, x = 3
Output: 1->2->2->4->3->5

A

maintain two list. l1, l2. If the valuse is lower then x. go to l1. otherwise go to l2. Then concat l1,l2 together,

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
  1. Reverse Linked List II
    Reverse a linked list from position m to n. Do it in one-pass.

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

A
The first loop goes m steps. And remember prev as m-1 node.
link cur to next.next, next to first of reverse, pre to next.
while(n-m):
            next = cur.next
            cur.next = next.next
            next.next = pre.next
            pre.next = next
            n -= 1
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q
  1. Reverse Linked List
    Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
Follow up:

A linked list can be reversed either iteratively or recursively. Could you implement both?

A
prev, cur = None, head
while(cur):
    tmp = cur.next
    cur.next = prev
    prev = cur
    cur = tmp
return prev
class Solution:
# @param {ListNode} head
# @return {ListNode}
def reverseList(self, head):
    return self._reverse(head)
def _reverse(self, cur, prev=None):
    if not cur:
        return prev
    tmp= cur.next
    cur.next = prev
    return self._reverse(tmp, node)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q
  1. Copy List with Random Pointer
    A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:

val: an integer representing Node.val
random_index: the index of the node (range from 0 to n-1) where random pointer points to, or null if it does not point to any node.

Example 1:

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
Output: [[7,null],[13,0],[11,4],[10,2],[1,0]]
Example 2:

Input: head = [[1,1],[2,1]]
Output: [[1,1],[2,1]]
Example 3:

Input: head = [[3,null],[3,0],[3,null]]
Output: [[3,null],[3,0],[3,null]]
Example 4:

Input: head = []
Output: []
Explanation: Given linked list is empty (null pointer), so return null.

Constraints:

-10000 <= Node.val <= 10000
Node.random is null or pointing to a node in the linked list.
Number of Nodes will not exceed 1000.

A
walk through the whole list. And copy the node.val to a new list. Meanwhile, use a hashmap to save the map of node and new node.
table = {None:None}
table[node]=copy_node.
loop the new list and old list.
copy_node.random = table[node.random]
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q
  1. Linked List Cycle
    Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.

Follow up:

Can you solve it using O(1) (i.e. constant) memory?

A
Use two pointer. Fast slow pointer. Fast always go two steps. slow always go one step.
public boolean hasCycle(ListNode head) {
    if (head == null || head.next == null) {
        return false;
    }
    ListNode slow = head;
    ListNode fast = head.next;
    while (slow != fast) {
        if (fast == null || fast.next == null) {
            return false;
        }
        slow = slow.next;
        fast = fast.next.next;
    }
    return true;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q
  1. Linked List Cycle II
    Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

Follow-up:
Can you solve it without using extra space?

A
  1. Use hashmap to memorize the node you have walked before. once met the node again, it is the begin of cycle.
  2. 這是要用算出來的
    主要做法就是fast, slow先一起走,直到遇到。遇到之後,head和slow一起走,遇到的地方就是起點。
    a head to first node of cycle
    b first node of cycle to the node fast and slow met
    c the node fast and slow met to the end of cycle
    從head走到cycle中間的點並且遇到a+b
    同時fast也走了a+b+nL = 2(a+b)
    所以 a+b = nL => nL - b = a -> (n-1)L + c = a
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
  1. Reorder List
    Given a singly linked list L: L0→L1→…→Ln-1→Ln,
    reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…

You may not modify the values in the list’s nodes, only nodes itself may be changed.

Example 1:

Given 1->2->3->4, reorder it to 1->4->2->3.
Example 2:

Given 1->2->3->4->5, reorder it to 1->5->2->4->3.

A

find the middle of the list.
Partition the list into two list.
Then reverse the second list.
Then loop the two list and merge together.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q
  1. Insertion Sort List
    Sort a linked list using insertion sort.

A graphical example of insertion sort. The partial sorted list (black) initially contains only the first element in the list.
With each iteration one element (red) is removed from the input data and inserted in-place into the sorted list

Algorithm of Insertion Sort:

Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
It repeats until no input elements remain.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4
Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

A

Use a dummy node and gradually grow the sorted list.
loop the unsorted list one by one and insert to the new list.
The insertion also need to loop the sorted list and insert the node once cur.next.val > insert.val
Some trick can speed up.
No need to always loop from the front of sorted list.
Only go back to front when cur.next.val>insert.val
Also can maintain a last node, directly check the last node. this trick can speed up a lot.

17
Q
  1. Sort List
    Sort a linked list in O(n log n) time using constant space complexity.

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4
Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

A

Always split list into two list.
And recursive split.
And merge two list.

recusive function
split list, call function, merge list

Also quick sort solution.

18
Q
  1. Reverse Nodes in k-Group
    Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

Example:

Given this linked list: 1->2->3->4->5

For k = 2, you should return: 2->1->4->3->5

For k = 3, you should return: 3->2->1->4->5

Note:

Only constant extra memory is allowed.
You may not alter the values in the list’s nodes, only nodes itself may be changed.

A

walk k step and reverse the k node. And keep going.
Until you can’t walk k step just stop.
No need to measure the length first.

19
Q

Memorize

A
常用功能
1. swap
prev->left->right->d
left.next = right.next
right.next = left
prev.next = right
2. Reverse
Iterative
prev = None
cur = head
while cur:
    tmp = cur.next    #存下一個
    cur.next = prev    #往回指
    prev = cur        # update
    cur = tmp        #update
return head
Recursive
class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head or not head.next:
            return head
        node = self.reverseList(head.next)
        head.next.next = head
        #node.next = head node always is last node, don't do this
        head.next = None
        return node
3. 找中點
slow, fast = head, head
while(fast.next and fast.next.next):
    slow = slow.next
    fast = fast.next.next
reverse_head = slow.next
slow.next = None
slow is middle

常見bug

  1. cur.next when cur is None

常用trick
1. Dummy node
使用時機:第一個node也可能要改變的情況,就先創一個dummy連到head,或是在創一個新的list的時候
2. Slow fast pointer
使用時機:1. 找中點 2. 是否有cycle
Linked List 主要都是 fast slow pointer
019. Remove Nth Node From End of List
061. Rotate List
142. Linked List Cycle II
這些題型都是要讓fast走到底,slow在fast前n個,然後做一些事情,找中點。
82. Remove Duplicates from Sorted List II
讓fast先走,某些情況slow再走
3. 走兩步檢查while(fast.next and fast.next.next)

20
Q
  1. Add Two Numbers II
    You are given two non-empty linked lists representing two non-negative integers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

You may assume the two numbers do not contain any leading zero, except the number 0 itself.

Follow up:
What if you cannot modify the input lists? In other words, reversing the lists is not allowed.

Example:

Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 8 -> 0 -> 7

A

Recursive
用recursive 先一直往後面走,在backtracking回來算前面的位數。

stack
存成一個stack,然後累加,順便產生list。這個比較快