# Leetcode | list

Time：2020-9-28

Write a program to find the starting node of the intersection of two single linked lists.

As shown in the following two linked lists: The intersection begins at node C1.
Example 1: Input: intersectval = 8, lista = [4,1,8,4,5], listb = [5,0,1,8,4,5], skipa = 2, skipb = 3
Output: reference of the node with value = 8
Input explanation: the value of the intersection node is 8 (note that if two lists intersect, it cannot be 0). Starting from the respective header, the linked list a is [4,1,8,4,5], and the linked list B is [5,0,1,8,4,5]. In a, there are two nodes before the intersection node; in B, there are three nodes before the intersection node.

be careful:

• If two linked lists have no intersection, null is returned
• After the results are returned, the two linked lists still need to keep the original structure.
• It can be assumed that there are no loops in the entire linked list structure.
• The program satisfies o (n) time complexity and only uses o (1) memory.

Explanation
Method 1
Two pointers are used to obtain the length of two linked lists, and the length difference is obtained`n`
The pointer of a long list runs from the beginning`n`Step, the pointer of the short chain list points to the pointer of the short chain header, and then the two pointers run backward synchronously until the two pointers intersect.

``````public class Solution {
//1. Calculate the length difference between two linked lists
int n = 0;
while (p1!=null){
p1 = p1.next;
n++;
}
while (p2!=null){
p2 = p2.next;
n--;
}
//P1 points to long chains and P2 to short chains
if (n>0){
}else {
}
n = Math.abs(n);
//Long chain takes n steps first
for (int i = 0; i<n; i++){
p1 = p1.next;
}
//P1, P2 go together
while(p1!=p2){
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
}``````

Method 2
The more concise method first makes the long list pointer reach the end of the same distance as the short list length.
P1 and P2 point to the linked list heada and headb respectively. If P1 runs first, P1 points to headb; if P2 runs out, P2 points to heada until P1 and P2 are the same.
For example, for a linked list:`A={1,3,5,7,9,11}`and`B={2,4,9,11}`, intersect at the node`9`The length difference between the two lists is 2. Then the list B is less than two nodes.
Pointer P2 runs first in linked list B, resets P2 to a, P1, P2 and continues to run backward synchronously. Pointer P1 will run through two more nodes in a, and P2 will also run two nodes in B simultaneously. At this time, the position pointed by P2 is exactly the part longer than that of list a and list B. Finally, P1 points to headb, and P1 and P2 are at the same distance from the end, so we just need to go backward synchronously until we meet the intersection point.

``````public class Solution {
while (p1!=p2){
}
return p1;
}
}``````

Time complexity O (M + n)
Space complexity O (1)

# 206. Reverse linked list (simple)

Source: leetcode

Example:

``````Input: 1 > 2 > 3 > 4 > 5 > null
Output: 5 > 4 > 3 > 2 > 1 > null``````

You can invert the list iteratively or recursively. Can you solve the problem in two ways?

1. iterative version

``````/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) { val = x; }
* }
*/
class Solution {
ListNode prev = null;
ListNode temp = null;

while (curr!=null){
temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
return prev;
}
}``````

Time complexity O (n)
Space complexity O (1)

2. Recursive version

``````class Solution {
}
return res;
}
}``````

Time complexity O (n)
Space complexity O (n)

1. Merge two ordered linked lists

Merge two ascending lists into a new ascending list and return. The new linked list is composed of all nodes of two given linked lists.

Example:

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

The merging part is similar to the merging part of merge sort

``````class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
while (l1!=null && l2!=null){
if (l1.val<=l2.val){
p.next = l1;
p = p.next;
l1 = l1.next;
}
else{
p.next = l2;
p = p.next;
l2 = l2.next;
}
}
//There is only one list that has not been traversed
p.next = l1 == null ? l2 : l1;
}
}``````

Time complexity: O (M + n)
Spatial complexity: O (1)

# 83. Remove duplicate elements from sorted list (simple)

Given a sort list, delete all duplicate elements so that each element appears only once.

Example 1:

``````Input: 1 - > 1 - > 2
Output: 1 - > 2``````

Example 2:

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

Explanation:
1. Double pointer

``````class Solution {
}
ListNode curr = pre.next;
while (curr != null){
if (curr.val != pre.val){
pre.next = curr;
pre = pre.next;
}
curr = curr.next;
}
pre.next = null;
}
}``````

2. Single pointer*

``````class Solution {
while (curr !=null && curr.next != null){
if (curr.val == curr.next.val){
curr.next  = curr.next.next ; // if the value of the current node is equal to that of the next node, the same node in the middle will be skipped
}else{
curr =  curr.next ; // otherwise, do not skip
}
}
}
}``````

Time complexity O (n)
Space complexity O (1)

# 19. Delete the last nth node of the linked list (medium)

Given a linked list, delete the last nth node of the list, and return the head node of the list.

Example:

``````Given a linked list: 1 - > 2 - > 3 - > 4 - > 5, and N = 2

When the penultimate node is deleted, the linked list becomes 1 - > 2 - > 3 - > 5
explain:

The given n guarantee is valid.``````

Can you try one scan?

One scan method
Using two pointers, the pointer P1 takes n steps first, and the other pointer P2 moves backward synchronously from the beginning node. At this time, the two pointers are separated by N pointers. When P1 reaches the end, P2 happens to be on the last N + 1 node. Delete the last nth node.

``````class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(-1);
ListNode pre = dummy;
while(curr!=null){
curr = curr.next;
If (n! = 0) {// curr
n--;
}After else {// curr takes n steps, pre starts walking
pre = pre.next;
}
}
pre.next = pre.next.next;
return dummy.next;
}
}``````

Time complexity O (L), l is the length of linked list
Space complexity O (1)

# 82. Delete duplicate elements II from sorted list

Given a sort list, delete all nodes with duplicate numbers, and keep only the numbers that do not appear repeatedly in the original list.

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``````

Explanation

Solution 1: tail inserting non repeated nodes

``````class Solution {
ListNode dummy = new ListNode();
ListNode tail = dummy;

//Find the node that does not repeat and insert the tail of the node after tail
//Record the repeat interval [I, J) with double pointer L, R. if the length of [I, J) is 1, then I is the non repeating node, tail inserted!
//If the length of [I, J) is not 1, then I is a repeating node without tail insertion

for (ListNode L = head, R = head; R != null; L = R){
while (R!= null && L.val == R.val){
R = R.next;
}
If (l.next = = R) {// the next node of L is r, then l is not a repeating element, but tail inserted
tail.next = L;
tail = L;
tail.next = null;
}
}
return dummy.next;
}
}``````

Time complexity: O (n)
Spatial complexity: O (1)

Solution 2: delete duplicate nodes

``````class Solution {
ListNode dummy = new ListNode(-1);

ListNode pre = dummy, cur = head;
while (cur != null && cur.next != null) {
if (cur.val != cur.next.val) {
if (pre.next != cur) pre.next = cur.next;
else pre = pre.next;
}
cur = cur.next;
}
if (pre.next != cur) pre.next = cur.next;
return dummy.next;
}
}``````

Time complexity: O (n)
Spatial complexity: O (1)

# 24. Nodes in pairwise exchange linked list (medium)

You can’t just change the values inside the nodes, you need to actually exchange nodes.

Example:

``Given 1 - > 2 - > 3 - > 4, you should return 2 - > 1 - > 4 - > 3``

Explanation:
1. Iteration ``````class Solution {
ListNode dummy = new ListNode(-1);
ListNode pre = dummy;
ListNode curr = dummy.next;
while (curr != null && curr.next != null){
ListNode temp = curr.next;
curr.next = curr.next.next;
temp.next = curr;
pre.next = temp;
pre = curr;
curr = curr.next;
}
return dummy.next;
}
}``````

Time complexity O (n)
Space complexity O (1)

2. Recursion

``````//Recursion
class Solution {
}

first.next  = swapPairs( second.next ）; // the next node of the first node is the check point after the exchange of nodes after the second node
second.next  =First; // the second node points to the first node
Return second; // the second node is now the header node, so the second node is returned
}
}``````

Time complexity: O (n)
Spatial complexity: O (n)

# 445. Add two numbers II * (medium)

Two non empty linked lists are given to represent two nonnegative integers. The highest digit is at the beginning of the list. Each node of them stores only a single number. Adding the two numbers returns a new linked list.
You can assume that neither of these numbers begins with zero except for the number 0.

What to do if the input list cannot be modified? In other words, you can’t flip the nodes in the list.

Example:

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

Explanation:
1. Borrowing stack
Two stacks are used to store the values of the two linked lists. Each time the corresponding digit sum is calculated, the top element of the stack will pop up and accumulate.

``````class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
//L1 stack
ListNode p = l1;
while (p != null){
stack1.push(p.val);
p = p.next;
}
//L2 stack
p = l2;
while (p != null){
stack2.push(p.val);
p = p.next;
}
Int carry = 0; // carry
while (!stack1.isEmpty() || !stack2.isEmpty() || carry!=0){
int sum = 0;
if (!stack1.isEmpty()){
sum += stack1.pop();
}
if (!stack2.isEmpty()){
sum += stack2.pop();
}
sum += carry;

//Find the remainder
//Insert new node
int remainder = sum % 10;
ListNode s = new ListNode(remainder);
s.next = dummy.next;
dummy.next = s;

Carry = sum / 10; // next round carry

}
return dummy.next;
}
}``````

Time complexity O (n + m)
Space complexity O (n + m)

# 234. Palindrome list * (medium)

Source: leetcode

Example 1:

``````Input: 1 - > 2
Output: false``````

Example 2:

``````Input: 1 - > 2 - > 2 - > 1
Output: true``````

Can you solve this problem with O (n) time complexity and O (1) space complexity?

1. Borrowing stack:
Considering that the stack structure is in reverse order when it comes out of the stack, the stack is used.
Scan the linked list once and store the values in the stack;
Scan the linked list again, scan each node to see if it is equal to the top element of the stack, and pop up an element. If each time is equal, it is a palindrome linked list.
Space complexity O (n)

2. Stack + speed pointer:
The second half of the list is put on the stack, and the first half of the list is compared with the stack.
(to find the midpoint, the fast pointer takes two steps at a time, and the slow pointer takes one step at a time)
Space complexity O (n / 2)

3. Fast / slow pointer + reverse linked list:
The second half of the list is in reverse order. Compare whether the two lists are equal.
The second half of the list is restored again.
Note:
First of all, regardless of whether the number of nodes in the list is odd or even, the rear split node is the next node of P1, so P1 is determined, and the latter half is determined.
Secondly, when the number of nodes in the list is odd, the length of the first half of the list is 1 more than that of the second half. However, in the comparison, the last node of the first half is not considered. As long as the pointer of the latter half of the list reaches the end, the comparison is successful.

Time complexity O (n + n / 2) = O (n);
Only constant pointers are used, so the space complexity is O (1) java code

``````/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) { val = x; }
* }
*/
class Solution {
//Define a fast pointer and a slow pointer
//Find the midpoint, P1 points to the midpoint, P2 points to the node after the midpoint
while(p2.next!=null && p2.next.next!=null){
p1 = p1.next;
p2 = p2.next.next;
}
p2 = p1.next;
p1.next = null;

//Reverse the second half of the list, Rev is the inverted list
ListNode p3 = null;
while (p2!=null){
ListNode temp = p2.next;
p2.next = p3;
p3 = p2;
p2 = temp;
}
ListNode rev = p3;

while(p3!=null){
if ( p1.val == p3.val){
p1 = p1.next;
p3 = p3.next;
}
else break;
}
if (p3 == null){
return true;
}else{
return false;
}
}
}``````

Time complexity O (n)
Space complexity O (1)

# 725. Split linked list * (medium)

Given a linked list whose head node is root, write a function to divide the list into k continuous parts.
The length of each part should be as equal as possible: the length difference between any two parts cannot exceed 1, which means that some parts may be null.
The K parts should be output in the order they appear in the linked list, and the length of the first part should be greater than or equal to the length of the following part.
Returns a list of linked lists that meet the above rules.

Example 1:

``````Input:
root = [1, 2, 3], k = 5
Output: [, , , [],]
Explanation:
The input and output parts should be linked lists, not arrays.
For example, the input node root has Val = 1, root.next.val  = 2, \ root.next.next . Val = 3, and root.next.next .next = null。
The first output  is output . Val = 1, output . Next = null.
The last element output  is null, which means that the last part is an empty linked list.``````

Example 2:

``````Input:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input is divided into several consecutive parts, and the length difference of each part is no more than 1. The length of the front part is greater than or equal to that of the back part.``````

Tips:
Length range of root: [0, 1000]
Enter the size range of each node: [0, 999]
The value range of K is: [1,50]

Explanation:

1. Construct a new linked list

First find the length of the list`n`, the length of each linked list in the array is at least`n/k`If`n%k = rem>0`, then the length of the first REM array plus`1`, for`len+1`. build a new linked list and add nodes of corresponding length to the list.

``````class Solution {
public ListNode[] splitListToParts(ListNode root, int k) {
ListNode[] res = new ListNode[k];

int n = 0;
ListNode curr = root;
while(curr!=null){
curr = curr.next;
n++;
}
int len = n / k;
Int REM = n% K; // the length of the first REM linked list is len + 1, and the length of the rest is len

curr = root;
for (int i = 0; i < k; i++){
ListNode dummy = new ListNode(-1);
ListNode p = dummy;

For (int j = 0; J < len + (REM > 0? 1:0); j + +) {// add nodes to each linked list

if (curr!=null){
p = p.next = new ListNode(curr.val);
curr = curr.next;
}
Else p.next = null; // if the original linked list is completely separated, put the empty list into the array not added to the linked list
}
res[i] = dummy.next;
REM --; // construct a linked list, REM minus 1
}
return res;
}
}``````

The time complexity is O (n + k). If K is large, k-1 empty nodes should be added at most
Space complexity O (max (n + k))

2. separate from the original list
Curr points to the current node and breaks after the corresponding length.

``````class Solution {
public ListNode[] splitListToParts(ListNode root, int k) {
ListNode[] res = new ListNode[k];
ListNode curr = root;
int n = 0;
while(curr!=null){
curr = curr.next;
n++;
}

int len = n/k;
int rem = n%k;

curr = root;
for (int i=0; i<k; i++){
res[i] = curr;
for(int j =0; j< len + (rem>0?1: 0)-1; j++){
if (curr!=null){
curr = curr.next;
}
}
//Disconnect
if (curr!=null){
ListNode temp = curr.next;
curr.next = null;
curr = temp;
}
rem--;
}
return res;
}
}``````

The time complexity is O (n + k). If K is large, k-1 empty nodes should be added at most
Space complexity O (k)

# 328. Parity list (medium)

Source: leetcode

Given a single linked list, all odd and even nodes are arranged together. Note that the odd and even nodes here refer to the parity of the node number, not the parity of the node’s value.
Try using the in place algorithm. The space complexity of your algorithm should be o (1), the time complexity should be o (nodes), nodes is the total number of nodes.

Example 1:

``````Input: 1 > 2 > 3 > 4 > 5 > null
Output: 1 > 3 > 5 > 2 > 4 > null``````

Example 2:

``````Input: 2 > 1 > 3 > 5 > 6 > 4 > 7 > null
Output: 2 > 3 > 6 > 7 > 1 > 5 > 4 > null``````

explain:
The relative order of odd and even nodes should be maintained.
The first node of a linked list is considered an odd node, the second node is considered an even node, and so on.

Explanation
Put odd nodes in one list and even nodes in another. Then connect the even list to the end of the odd list.

``````public class Solution {
if (head == null) return null;
while (even != null &&  even.next  ! = null) {// note the boundary conditions
odd.next = even.next;
odd = odd.next;
even.next = odd.next;
even = even.next;
}