Reversal problem
2021.02.11
No. 25 K flip linked list
Give you a linked list, each group of k nodes will be flipped, please return to the flipped linked list.
k is a positive integer, and its value is less than or equal to the length of the linked list.
If the total number of nodes is not an integral multiple of k, please keep the last remaining nodes in the original order.
Example:
Give you this linked list: 1->2->3->4->5
When k = 2, it should return: 2->1->4->3->5
When k = 3, it should return: 3->2->1->4->5
instruction:
Your algorithm can only use constant extra space.
You can't just change the value inside the node, but need to actually exchange the node.
Source: LeetCode
Link: https://leetcode-cn.com/problems/reverse-nodes-in-k-group
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=25 lang=javascript
*
* [25] K 个一组翻转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
// 链表转数组
const list2Arr = head => {
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 对k个节点进行数组切割即可
const kReverse = (a,k) => {
const r = [];
let cnt = 0;
while(a.length >= k + cnt)
{
let tmp = a.slice(cnt, cnt+k);
tmp.reverse();
tmp.map( (x)=> r.push(x));
cnt += k;
}
a.slice(cnt).map( (x)=> r.push(x));
return r;
}
return arr2List(kReverse(list2Arr(head), k));
};
Option II:
/*
* @lc app=leetcode.cn id=25 lang=javascript
*
* [25] K 个一组翻转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
let cur = head;
let count = 0;
// 求k个待反转元素的首节点和尾节点
while(cur != null && count != k){
cur = cur.next;
count++;
}
// 足够k个节点,去反转
if(count == k){
// 递归链接后续k个反转的链表头节点
cur = reverseKGroup(cur,k);
while(count != 0){
count--;
// 反转链表
let tmp = head.next;
head.next = cur;
cur = head;
head = tmp;
}
head = cur;
}
return head;
};
third solution:
/*
* @lc app=leetcode.cn id=25 lang=javascript
*
* [25] K 个一组翻转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
if(!head) return null;
// 反转链表
let reverse = (a,b) => {
let pre;
let cur = a;
let next = b;
while(cur != b){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
// 反转区间a-b的k个待反转的元素
let a = head;
let b = head;
for(let i = 0;i < k;i++){
// 不足k个,不需要反转
if(!b) return head;
b = b.next;
}
// 反转前k个元素
let newHead = reverse(a,b);
// 递归链接后续反转链表
a.next = reverseKGroup(b,k);
return newHead;
};
Option Four:
/*
* @lc app=leetcode.cn id=25 lang=javascript
*
* [25] K 个一组翻转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
let stack = [];
let preHead = new ListNode(0);
let pre = preHead;
// 循环链接后续反转链表
while(true){
let count = 0;
let tmp = head;
while(tmp && count < k){
stack.push(tmp);
tmp = tmp.next;
count++;
}
// 不够k个,直接链接剩下链表返回
if(count != k){
pre.next = head;
break;
}
// 出栈即是反转
while(stack.length > 0){
pre.next = stack.pop();
pre = pre.next;
}
pre.next = tmp;
head = tmp;
}
return preHead.next;
};
Option five:
/*
* @lc app=leetcode.cn id=25 lang=javascript
*
* [25] K 个一组翻转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var reverseKGroup = function(head, k) {
const myReverse = (head, tail) => {
let prev = tail.next;
let p = head;
while (prev !== tail) {
const nex = p.next;
p.next = prev;
prev = p;
p = nex;
}
return [tail, head];
}
const hair = new ListNode(0);
hair.next = head;
let pre = hair;
while (head) {
let tail = pre;
// 查看剩余部分长度是否大于等于 k
for (let i = 0; i < k; ++i) {
tail = tail.next;
if (!tail) {
return hair.next;
}
}
const nex = tail.next;
[head, tail] = myReverse(head, tail);
// 把子链表重新接回原链表
pre.next = head;
tail.next = nex;
pre = tail;
head = tail.next;
}
return hair.next;
};
There are five solutions: 1. Use arrays to solve, which is cumbersome, you need to switch to an array and then cut back; 2. Recursive related solutions, use stacks, iterations, etc. for analysis; 3. Use dummy front nodes to reduce the complexity to a constant Level, very clever
2021.02.12
No.61 Rotating Linked Watch
Given a linked list, rotate the linked list and move each node of the linked list k positions to the right, where k is a non-negative number.
Example 1:
Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
explain:
Rotate 1 step to the right: 5->1->2->3->4->NULL
Rotate right 2 steps: 4->5->1->2->3->NULL
Example 2:
Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
explain:
Rotate right 1 step: 2->0->1->NULL
Rotate right 2 steps: 1->2->0->NULL
Rotate right 3 steps: 0->1->2->NULL
Rotate right 4 steps: 2->0->1->NULL
Source: LeetCode
Link: https://leetcode-cn.com/problems/rotate-list
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=61 lang=javascript
*
* [61] 旋转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function(head, k) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 数组位置变化
const arrRotate = (a, k) => {
const len = a.length;
const hashTable = {};
for(let i=0; i< a.length; i++) {
hashTable[(i+k) % len] = a[i]
};
return Object.values(hashTable)
};
return arr2List(arrRotate(list2Arr(head), k));
};
Option II:
/*
* @lc app=leetcode.cn id=61 lang=javascript
*
* [61] 旋转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function (head, k) {
if (!head || k === 0) return head; // 特判
let p = head, len = 1;
while (p.next) {
p = p.next;
len++;
}
p.next = head; // 首尾相接
k = len - k % len; // 处理要移动的距离
while (k--) p = p.next;
head = p.next; // head 指向第 len - k + 1 个节点,即答案
p.next = null; // 切断 len - k 与 len - k + 1 的关系
return head;
}
third solution:
/*
* @lc app=leetcode.cn id=61 lang=javascript
*
* [61] 旋转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function(head, k) {
if(head===null||head.next===null)return head;
let len = 0;//链表长度
let p = head;
let first = head;//第一个结点
let stack = [];//辅助栈
while(p){
stack.push(p);
p = p.next;
len++;
}
p = stack.pop();
for(let i = 1;i<=k%len;i++){
p.next = first;
stack.unshift(p);
first = p;
p = stack.pop();
p.next = null;
}
return first;
};
Option Four:
/*
* @lc app=leetcode.cn id=61 lang=javascript
*
* [61] 旋转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
var rotateRight = function(head, k) {
var order = new ListNode(0,head); // head链表的copy
var fast = new ListNode(0,head); // 快指针
var slow = new ListNode(0,head); // 慢指针
var count = 0; // 链表长度
while(order && order.next){ // 循环求链表长度
order = order.next;
count ++;
}
var n = k % count; // 因为 k > 链表长度 时,出现重复操作。对 k 求余,去除重复
for (var i = 0; i < n; i++){ // 快指针先走 n 步
fast = fast.next;
}
while(fast && fast.next){ // 链表的快指针、慢指针操作
fast = fast.next;
slow = slow.next;
}
// 两步操作
// 第一、将倒数第 k%count 元素 与 倒数第 (k%count-1) 元素 断开
var resultPre = slow.next; // 序号2 返回结果集的 起始位置
var result = resultPre; // 序号3 最后return的结果集
slow.next = null; // 将链表断开
// 第二、再讲链表的尾部与头部链接
while(resultPre && resultPre.next) {
resultPre = resultPre.next
}
if (resultPre){
resultPre.next = head; // 情况1:旋转链表后有改变,将链表拼接起来
}
else {
result = head; // 情况2: 旋转链表后没有改变,返回原始链表
}
return result;
};
Option five:
/*
* @lc app=leetcode.cn id=61 lang=javascript
*
* [61] 旋转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} k
* @return {ListNode}
*/
const rotateRight = (head, k) => {
if (!head || !head.next) return head
let curr = head, n = 0
// 遍历链表计算其长度
while (++n && curr.next) curr = curr.next
k = k % n // 去重
// 链表右移
while (k--) {
curr = head
while (curr.next.next) curr = curr.next
// 这里curr是链表的打断位置,即倒数第二项
curr.next.next = head // 链表最后一项指向头部形成环
head = curr.next // 定位新的头节点
curr.next = null // 打断链表环
}
return head
}
There are five ideas for this question: 1. Hash table storage, use the position of the array to perform hash convergence and divergence to generate a new linked list; 2. The linked list is formed into a ring, and the corresponding position is cut; 3. The stack assists in processing the loop cut position; 4. The speed pointer , Process according to the position distance of the double pointer, and use the other two pointers to record the new cut position; 5. Routine exhaustion, step by step
2021.02.13
No.92 Flip the linked list-ii
Reverse the linked list from position m to n. Please use one scan to complete the reversal.
instruction:
1 ≤ m ≤ n ≤ length of the linked list.
Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL
Source: LeetCode
Link: https://leetcode-cn.com/problems/reverse-linked-list-ii
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=92 lang=javascript
*
* [92] 反转链表 II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} m
* @param {number} n
* @return {ListNode}
*/
var reverseBetween = function(head, m, n) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 数组 m => n 翻转
const reversePosition = (a, m, n) => {
return [...a.slice(0,m-1), ...a.slice(m-1,n).reverse(), ...a.slice(n)]
};
return arr2List(reversePosition(list2Arr(head),m,n));
};
Option II:
/*
* @lc app=leetcode.cn id=92 lang=javascript
*
* [92] 反转链表 II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} m
* @param {number} n
* @return {ListNode}
*/
var reverseBetween = function(head, m, n) {
// step1 => 双指针p1,p2保持固定间距
const dummyHead = new ListNode(0, head);
let p1 = p2 = head;
let step2 = n - m;
while (step2-- > 0) {
p2 = p2.next;
}
let step1 = m - 1;
let tmpHead = p1;
while (step1-- > 0) {
tmpHead = p1;
p1 = p1.next;
p2 = p2.next;
}
// step2 => 极其重要的测试case:p1指针压根没动【dummyHead就起作用了】
if (p1 == head) {
tmpHead = dummyHead;
}
// step3 => 尾插法
let tmp = p1;
while (tmp != p2) {
tmp = p1.next;
p1.next = tmp.next;
tmp.next = tmpHead.next;
tmpHead.next = tmp;
}
return dummyHead.next;
};
Two solutions: 1. Convert to an array, using the slice and reverse splicing of the array; 2. Double pointer + tail interpolation, using the exchange of head and tail pointers
2021.02.14
No.206 Reverse Linked List
Reverse a singly linked list.
example:
input: 1->2->3->4->5->NULL
output: 5->4->3->2->1->NULL
Option One:
/*
* @lc app=leetcode.cn id=206 lang=javascript
*
* [206] 反转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 数组 m => n 翻转
const reverseList = (a) => {
return a.reverse()
};
return arr2List(reverseList(list2Arr(head)));
};
Option II:
/*
* @lc app=leetcode.cn id=206 lang=javascript
*
* [206] 反转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let prev = null;
let curr = head;
while (curr) {
const next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
};
third solution:
/*
* @lc app=leetcode.cn id=206 lang=javascript
*
* [206] 反转链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
if (head == null || head.next == null) {
return head;
}
const newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
};
Three methods: 1. Convert to an array and use the reverse of the array; 2. Iterate; 3. Recursion
Summarize:
- The common problem of inverting linked list is to use the three pointers of the linked list to perform related inversions. The common ones are the related deformations of the head pointer, tail pointer and replacement pointer. Data structures such as the stack can be used for iteration or recursion;
- A clever way to reverse the problem is to convert it into an array and use the related API of the array for processing, and then convert the array into a linked list.
Separate and merge
2021.02.18
No.21 Combine two ordered linked lists
Combine two ascending linked lists into a new ascending linked list and return. The new linked list is composed by splicing all the nodes of the given two linked lists.
Example 1:
Input: l1 = [1,2,4], l2 = [1,3,4]
Output: [1,1,2,3,4,4]
Example 2:
Input: l1 = [], l2 = []
Output: []
Example 3:
Input: l1 = [], l2 = [0]
Output: [0]
hint:
The range of the number of nodes in the two linked lists is [0, 50]
-100 <= Node.val <= 100
l1 and l2 are arranged in non-decreasing order
Source: LeetCode
Link: https://leetcode-cn.com/problems/merge-two-sorted-lists
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=21 lang=javascript
*
* [21] 合并两个有序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
if(!l1) return l2;
if(!l2) return l1;
while(l1 != null && l2 != null) {
if(l1.val <= l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
};
Option II:
/*
* @lc app=leetcode.cn id=21 lang=javascript
*
* [21] 合并两个有序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
let prev = new ListNode(-1),
head = prev;
while(l1 != null && l2 != null) {
if(l1.val <= l2.val) {
head.next = l1;
l1 = l1.next;
} else {
head.next = l2;
l2 = l2.next;
}
head = head.next;
}
head.next = l1 === null ? l2 : l1;
return prev.next;
};
third solution:
/*
* @lc app=leetcode.cn id=21 lang=javascript
*
* [21] 合并两个有序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 两个数组合并排序
const mergeArr = (a1,a2) => {
return [...a1,...a2].sort((a,b) => a-b);
}
return arr2List(mergeArr(list2Arr(l1), list2Arr(l2)));
};
There are three schemes: 1. Recursion, using implicit stacks to merge linked lists; 2. Iterative, using double pointers for iterative judgment; 3. Converting to arrays and merging in ascending order
2021.02.21
No.23 Combine k ascending linked lists
Give you an array of linked lists, each of which has been arranged in ascending order.
Please merge all linked lists into an ascending linked list and return the merged linked list.
Example 1:
Input: lists = [[1,4,5],[1,3,4],[2,6]]
Output: [1,1,2,3,4,4,5,6]
Explanation: The linked list array is as follows:
[
1->4->5,
1->3->4,
2->6
]
Combine them into an ordered linked list to get.
1->1->2->3->4->4->5->6
Example 2:
Enter: lists = []
Output: []
Example 3:
Input: lists = [[]]
Output: []
hint:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= listsi <= 10^4
lists[i] in ascending order
The sum of lists[i].length does not exceed 10^4
Source: LeetCode
Link: https://leetcode-cn.com/problems/merge-k-sorted-lists
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=23 lang=javascript
*
* [23] 合并K个升序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function(lists) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 对k个节点进行数组切割即可
const mergeArr = lists => {
const r = [];
lists.forEach(list => r.push(...list2Arr(list)))
return r.sort((a,b) => a-b);
}
return arr2List(mergeArr(lists));
};
Option II:
/*
* @lc app=leetcode.cn id=23 lang=javascript
*
* [23] 合并K个升序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function(lists) {
// 合并两个链表
const mergeTwoLists = function(l1, l2) {
let prev = new ListNode(-1),
head = prev;
while(l1 != null && l2 != null) {
if(l1.val <= l2.val) {
head.next = l1;
l1 = l1.next;
} else {
head.next = l2;
l2 = l2.next;
}
head = head.next;
}
head.next = l1 === null ? l2 : l1;
return prev.next;
};
// 分治
const merge = (lists, l, r) => {
if (l == r) return lists[l];
if (l > r) return null;
const mid = (l + r) >> 1;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
};
return merge(lists, 0, lists.length - 1);
};
third solution:
/*
* @lc app=leetcode.cn id=23 lang=javascript
*
* [23] 合并K个升序链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function(lists) {
let queue = new PriorityQueue();
lists.forEach(list => {
if(list) queue.enqueue(list, list.val)
});
let res = new ListNode(-1);
let cur = res;
while(!queue.isEmpty()) {
cur.next = queue.dequeue();
cur = cur.next;
if(cur.next) queue.enqueue(cur.next, cur.next.val);
}
return res.next;
}
class Node {
constructor(val, priority) {
this.val = val;
this.priority = priority;
}
}
class PriorityQueue {
constructor() {
this.values = [];
}
enqueue(val, priority) {
let node = new Node(val, priority);
this.values.push(node);
this.bubbleUp();
}
dequeue() {
let max = this.values[0];
let end = this.values.pop();
if(this.values.length) {
this.values[0] = end;
this.bubbleDown();
}
return max.val;
}
isEmpty() {
return !this.values.length;
}
bubbleUp(index = this.values.length - 1) {
if(index <= 0) return;
let parentIndex = Math.floor((index - 1) / 2);
if(this.values[index].priority <= this.values[parentIndex].priority) {
[this.values[index], this.values[parentIndex]] = [this.values[parentIndex], this.values[index]];
this.bubbleUp(parentIndex);
}
}
bubbleDown(index = 0, swapIndex = null) {
let leftIndex = index * 2 + 1,
rightIndex = index * 2 + 2,
length = this.values.length;
if(leftIndex < length) {
if(this.values[leftIndex].priority <= this.values[index].priority) {
swapIndex = leftIndex;
}
}
if(rightIndex < length) {
if((swapIndex === null && this.values[rightIndex].priority <= this.values[index].priority) || (swapIndex !== null && this.values[rightIndex].priority <= this.values[leftIndex].priority)) {
swapIndex = rightIndex;
}
}
if(swapIndex !== null) {
[this.values[index], this.values[swapIndex]] = [this.values[swapIndex], this.values[index]];
this.bubbleDown(swapIndex, null);
}
}
};
There are three solutions: 1. Use an array to solve, and finally convert the array to a linked list; 2. Combine and merge the two linked lists and optimize using the divide and conquer algorithm; 3. Construct a priority queue for optimization, and use space for time
2021.02.22
No.86 Separate Linked List
Given the head node head of a linked list and a specific value x, please separate the linked list so that all nodes less than x appear before nodes greater than or equal to x.
You should keep the initial relative position of each node in the two partitions.
Example 1:
Input: head = [1,4,3,2,5,2], x = 3
Output: [1,2,2,4,3,5]
Example 2:
Input: head = [2,1], x = 2
Output: [1,2]
hint:
The number of nodes in the linked list is in the range [0, 200]
-100 <= Node.val <= 100
-200 <= x <= 200
Source: LeetCode
Link: https://leetcode-cn.com/problems/partition-list
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=86 lang=javascript
*
* [86] 分隔链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
let a = new ListNode(0),
b = new ListNode(0);
const ahead = a,
bhead = b;
while(head) {
if(head.val < x) {
a.next = head;
a = a.next;
} else {
b.next = head;
b = b.next;
}
head = head.next;
}
a.next = bhead.next;
b.next = null;
return ahead.next;
};
Option II:
/*
* @lc app=leetcode.cn id=86 lang=javascript
*
* [86] 分隔链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} x
* @return {ListNode}
*/
var partition = function(head, x) {
// 链表转数组
const list2Arr = head => {
if(!head) return [];
const a = [head.val];
while(head.next) {a.push(head.next.val);head = head.next;}
return a;
}
// 数组转链表
const arr2List = arr => {
if(arr.length == 0) return null;
let head = new ListNode(arr[0]);
let cur = head;
for(let i=1; i < arr.length; i++) {
cur.next = new ListNode(arr[i]);
cur = cur.next;
};
return head;
};
// 数组排序
const arrSort = (arr, x) => {
return [...arr.filter(a => a < x), ...arr.filter(a => a >= x)];
};
return arr2List(arrSort(list2Arr(head), x))
};
There are two solutions: 1. Divide into a large and small linked list and merge; 2. Use the array api to sort
2021.03.02
No.725 Separate Linked List
Given a linked list whose head node is root, write a function to divide the linked list into k consecutive 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 in which they appear in the linked list, and the length of the part in the front should be greater than or equal to the length in the back.
Return a list of linked lists that meet the above rules.
Example: 1->2->3->4, k = 5 // 5 result [[1], [2], [3], [4], null]
Example 1:
enter:
root = [1, 2, 3], k = 5
Output: [[1],[2],[3],[],[]]
explain:
Each part of the input and output should be a linked list, not an array.
For example, the input node root has val = 1, root.next.val = 2, oot.next.next.val = 3, and root.next.next.next = null.
The first output output[0] is output[0].val = 1, output[0].next = null.
The last element output[4] is null, which represents the last part of the empty linked list.
Example 2:
enter:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
explain:
The input is divided into several consecutive parts, and the length of each part does not differ by more than 1. The length of the front part is greater than or equal to the length of the back part.
hint:
The length range of root: [0, 1000].
Enter the size range of each node: [0, 999].
The value range of k: [1, 50].
Source: LeetCode
Link: https://leetcode-cn.com/problems/split-linked-list-in-parts
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Program:
/*
* @lc app=leetcode.cn id=725 lang=javascript
*
* [725] 分隔链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} root
* @param {number} k
* @return {ListNode[]}
*/
var splitListToParts = function (root, k) {
// 1. 获取链表的长度
const getRootLength = root => {
let n = 0;
while (root) {
n++;
root = root.next;
};
return n;
};
// 2. 分析链表的分割方式
// b项是 a+1;k-b项是 a
const len = getRootLength(root),
a = ~~(len / k),
b = len % k;
// 3. 分割链表
const r = []; // 返回的链表数组
// 循环链表
for(let m = 1;m<=k;m++) {
if(!root) {
r.push(null);
continue;
}
let p1 = root,
p2 = root,
num = a;
if(m<=b) {
while(num-->0) p2 = p2.next;
} else {
num -=1;
while(num-->0) p2 = p2.next;
};
// 处理p2为null
if(!p2) {
r.push(p1);
root = null;
continue;
}
root = p2.next;
p2.next = null;
r.push(p1);
}
return r;
};
The key lies in the separation of k, the judgment of different segmentation lengths, and the need to pay attention to the processing of boundary conditions
Summarize:
- Combination and division of linked lists The main structure of new linked lists needs to be split and combined according to requirements. Commonly constructed linked lists include double pointer method and stack method
- In particular, because js does not have its own linked list structure, it can convert the linked list into an array and use the relevant api to process
Delete node
2021.03.04
No.203 Remove linked list elements
Delete all nodes in the linked list that are equal to the given value val
example:
input: 1->2->6->3->4->5->6, val = 6
output: 1->2->3->4->5
Program:
/*
* @lc app=leetcode.cn id=203 lang=javascript
*
* [203] 移除链表元素
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
if(!head) return null;
let p = phead = new ListNode(null);
p.next = head;
while(p.next) {
if(p.next.val == val) {
p.next = p.next.next;
} else {
p = p.next;
}
}
return phead.next;
};
The structure of the linked list, using the dummy node to construct the head pointer for double pointer traversal
2021.03.06
No.19 Delete the Nth node from the bottom of the linked list
Give you a linked list, delete the nth node from the bottom of the linked list, and return the head node of the linked list.
Advanced: Can you try to use a scan to achieve it?
Example 1:
Input: head = [1,2,3,4,5], n = 2
Output: [1,2,3,5]
Example 2:
Input: head = [1], n = 1
Output: []
Example 3:
Input: head = [1,2], n = 1
Output: [1]
hint:
The number of nodes in the linked list is sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=19 lang=javascript
*
* [19] 删除链表的倒数第 N 个结点
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
let p = head, q = head, m = phead = new ListNode(head);
m.next = head;
// 将q指针变为 q = head.next···next 有n个next
for( let _n = n; _n > 0; _n-- ) {
q = head.next;
head = head.next;
};
// 当q为null时 停止遍历
while(q) {
p = p.next;
q = q.next;
m = m.next;
};
// 删除此时q的节点
p = p.next;
m.next = p;
return phead.next;
};
Option II:
/*
* @lc app=leetcode.cn id=19 lang=javascript
*
* [19] 删除链表的倒数第 N 个结点
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
let lastN = 0;
const recursion = (head) => {
if (!head) {
return null;
}
const next = recursion(head.next);
lastN++;
if (lastN === n) {
head = next;
}
if (lastN === n + 1) {
head.next = next;
}
return head;
};
return recursion(head);
};
third solution:
/*
* @lc app=leetcode.cn id=19 lang=javascript
*
* [19] 删除链表的倒数第 N 个结点
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
const nowHead = [head];
let tempHead = head;
while (tempHead.next) {
nowHead.push(tempHead.next);
tempHead = tempHead.next;
}
let lastN = 0;
let isHead = true;
while (nowHead.length) {
lastN++;
const now = nowHead.pop();
if (lastN - 1 === n) {
isHead = false;
now.next = now.next.next;
}
}
if (isHead) {
head = head.next;
}
return head;
};
There are three options: 1. Fast and slow pointers, set the distance between the fast and slow pointers to n to traverse; 2. Recursion; 3. Iteration
2021.03.09
No.82 Delete duplicate elements in the sorted list ii
Given a sorted linked list, delete all nodes with repeated numbers, and only keep the numbers that are not repeated in the original linked 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
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Program:
/*
* @lc app=leetcode.cn id=82 lang=javascript
*
* [82] 删除排序链表中的重复元素 II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var deleteDuplicates = function (head) {
if (!head) return null;
let h = p = new ListNode(head),
q = head;
h.next = head;
p.next = head
while (q && q.next) {
if ( q.val == q.next.val) {
while(q.next && q.val == q.next.val) q = q.next;
p.next = q.next;
} else {
p = p.next;
}
q = q.next;
}
return h.next;
};
Double pointer processing, need to pay attention to boundary processing
2021.03.10
No. 83 Delete duplicate elements in the sorted list
Given a sorted linked 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
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=83 lang=javascript
*
* [83] 删除排序链表中的重复元素
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var deleteDuplicates = function(head) {
if(!head) return null;
let h = p = new ListNode(head),
q = head;
h.next = head;
p.next = head;
while(q && q.next) {
if(q.next.val == q.val) {
while(q.next && q.next.val == q.val) {
q = q.next;
}
p.next = q;
}
p = p.next;
q = q.next;
};
return h.next;
};
Option II:
/*
* @lc app=leetcode.cn id=83 lang=javascript
*
* [83] 删除排序链表中的重复元素
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var deleteDuplicates = function(head) {
if(!head || !head.next) return head;
head.next = deleteDuplicates(head.next);
if(head.next.val == head.val) {
head.next = head.next.next;
}
return head;
};
Same as Question 82, there are two solutions: 1. Fast and slow pointers, or single pointer traversal; 2. Recursion
2021.03.11
No.237 Delete a node in the linked list
Please write a function to delete a given (non-end) node in a linked list. The only parameter passed into the function is the node to be deleted.
There is a linked list - head = [4,5,1,9], which can be expressed as:
Example 1:
Input: head = [4,5,1,9], node = 5
Output: [4,1,9]
Explanation: Given the second node in your linked list with a value of 5, after calling your function, the linked list should become 4 -> 1 -> 9.
Example 2:
Input: head = [4,5,1,9], node = 1
Output: [4,5,9]
Explanation: Given the third node whose value is 1 in your linked list, after calling your function, the linked list should become 4 -> 5 -> 9.
hint:
The linked list contains at least two nodes.
The values of all nodes in the linked list are unique.
The given node is not the end node and must be a valid node in the linked list.
Don't return any results from your function.
Source: LeetCode
Link: https://leetcode-cn.com/problems/delete-node-in-a-linked-list
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Program:
/*
* @lc app=leetcode.cn id=237 lang=javascript
*
* [237] 删除链表中的节点
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} node
* @return {void} Do not return anything, modify node in-place instead.
*/
var deleteNode = function(node) {
if(!node) return null;
node.val = node.next.val;
node.next = node.next.next;
};
There is no head node to delete the node plan, to move flowers and trees, you need to replace the current value, and then delete the next node value
Summarize:
- The most common solution for deleting nodes is traversal deletion of fast and slow pointers, fast pointer exploration, and slow pointer as the last link list path that needs to be returned to control the node accordingly;
- You can also use extra space such as recursion, iteration, and stacks in exchange for corresponding time efficiency
Special linked list
2021.03.15
No.141 Circular Linked Watch
Given a linked list, determine whether there is a ring in the linked list.
If there is a node in the linked list that can be reached again by continuously tracking the next pointer, there is a ring in the linked list. In order to represent the rings in a given linked list, we use the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, then there is no ring in the linked list. Note: pos is not passed as a parameter, just to identify the actual situation of the linked list.
If there is a ring in the linked list, return true. Otherwise, it returns false.
Advanced:
Can you solve this problem with O(1) (ie, constant) memory?
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a ring in the linked list, and its tail is connected to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: true
Explanation: There is a ring in the linked list, the tail of which is connected to the first node.
Example 3:
Input: head = [1], pos = -1
Output: false
Explanation: There are no rings in the linked list.
hint:
The range of the number of nodes in the linked list is [0, 104]
-105 <= Node.val <= 105
pos is -1 or a valid index in the linked list.
Source: LeetCode
Link: https://leetcode-cn.com/problems/linked-list-cycle
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=141 lang=javascript
*
* [141] 环形链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if(!head) return false;
let hash = new Map();
while(head) {
if(hash.has(head)) return true;
hash.set(head, true);
head = head.next;
}
return false;
};
Option II:
/*
* @lc app=leetcode.cn id=141 lang=javascript
*
* [141] 环形链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
let fast = head;
let slow = head;
while (fast) {
if (fast.next == null) return false;
slow = slow.next;
fast = fast.next.next;
if (slow == fast) return true;
}
return false;
};
third solution:
/*
* @lc app=leetcode.cn id=141 lang=javascript
*
* [141] 环形链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
try {
JSON.stringify(head)
return false
} catch {
return true
}
};
There are three solutions: 1. Construct a hash table; 2. Judge the fast or slow pointer; 3. Take tricks and use JSON.stringify to avoid circular references
2021.04.26
No.160 Intersecting Linked List
Write a program to find the starting node where two singly linked lists intersect.
Such as the following two linked lists:
The intersection starts 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 linked lists intersect, it cannot be 0). Starting from the respective headers, linked list A is [4,1,8,4,5] and linked list B is [5,0,1,8,4,5]. In A, there are 2 nodes before the intersecting node; in B, there are 3 nodes before the intersecting node.
Example 2:
Input: intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
Output: Reference of the node with value = 2
Input explanation: The value of the intersection node is 2 (note that if two linked lists intersect, it cannot be 0). Starting from the respective headers, linked list A is [0,9,1,2,4], and linked list B is [3,2,4]. In A, there are 3 nodes before the intersecting node; in B, there are 1 node before the intersecting node.
Example 3:
Input: intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
Output: null
Input explanation: Counting from the respective headers, linked list A is [2,6,4], and linked list B is [1,5]. Since these two linked lists do not intersect, intersectVal must be 0, and skipA and skipB can be arbitrary values.
Explanation: The two linked lists do not intersect, so null is returned.
Notice:
If there is no intersection between the two linked lists, null is returned.
After returning the result, the two linked lists must still maintain the original structure.
It can be assumed that there are no cycles in the entire linked list structure.
The program tries to satisfy O(n) time complexity, and only uses O(1) memory.
Source: LeetCode
Link: https://leetcode-cn.com/problems/intersection-of-two-linked-lists
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=160 lang=javascript
*
* [160] 相交链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
if (!headA || !headB) return null;
let pA = headA;
while (pA) {
let pB = headB;
while (pB) {
if (pA === pB) return pA;
pB = pB.next;
}
pA = pA.next;
}
};
Option II:
/*
* @lc app=leetcode.cn id=160 lang=javascript
*
* [160] 相交链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
if (!headA || !headB) return null;
const hashmap = new Map();
let pA = headA;
while (pA) {
hashmap.set(pA, 1);
pA = pA.next;
}
let pB = headB;
while (pB) {
if (hashmap.has(pB)) return pB;
pB = pB.next;
}
};
third solution:
/*
* @lc app=leetcode.cn id=160 lang=javascript
*
* [160] 相交链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
if (!headA || !headB) return null;
let pA = headA,
pB = headB;
while(pA != pB) {
pA = pA === null ? headB : pA.next;
pB = pB === null ? headA : pB.next;
}
return pA;
};
Option Four:
/*
* @lc app=leetcode.cn id=160 lang=javascript
*
* [160] 相交链表
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
var getIntersectionNode = function (headA, headB) {
let aNum = 0
let bNum = 0
let short = headA
let long = headB
let tempA = headA
let tempB = headB
while (short) {
aNum += 1
short = short.next
}
while (long) {
bNum += 1
long = long.next
}
if (aNum > bNum) {
let dig = aNum - bNum
for (let i = 0; i < dig; i++) {
tempA = tempA.next
}
while (tempA) {
if(tempA == tempB) {
return tempA
} else {
tempA = tempA.next
tempB = tempB.next
}
}
}
if (aNum < bNum) {
let dig = bNum - aNum
for (let i = 0; i < dig; i++) {
tempB = tempB.next
}
while (tempA) {
if(tempA == tempB) {
return tempA
} else {
tempA = tempA.next
tempB = tempB.next
}
}
}
if (aNum = bNum) {
while (tempA) {
if(tempA == tempB) {
return tempA
} else {
tempA = tempA.next
tempB = tempB.next
}
}
}
};
There are four schemes: 1. Break solution, let A go to B; 2. traverse once to generate a hash table, and then judge; 3. form a cross circular linked list, cross traverse; 4. traverse first to calculate the longest table, let the most The long watch goes first and then judges synchronously
2021.04.27
No.142 Circular Linked Watch ii
Given a linked list, return the first node where the linked list starts to enter the loop. If the linked list has no rings, null is returned.
In order to represent the rings in a given linked list, we use the integer pos to indicate the position where the end of the linked list is connected to the linked list (the index starts from 0). If pos is -1, then there is no ring in the linked list. Note that pos is only used to identify the ring, and will not be passed to the function as a parameter.
Note: It is not allowed to modify the given linked list.
Advanced:
Can you solve this problem using O(1) space?
Example 1:
Input: head = [3,2,0,-4], pos = 1
Output: return the linked list node with index 1
Explanation: There is a ring in the linked list, and its tail is connected to the second node.
Example 2:
Input: head = [1,2], pos = 0
Output: return the linked list node with index 0
Explanation: There is a ring in the linked list, the tail of which is connected to the first node.
Example 3:
Input: head = [1], pos = -1
Output: return null
Explanation: There are no rings in the linked list.
hint:
The range of the number of nodes in the linked list is in the range [0, 104]
-105 <= Node.val <= 105
The value of pos is -1 or a valid index in the linked list
Source: LeetCode
Link: https://leetcode-cn.com/problems/linked-list-cycle-ii
The copyright belongs to Lingkou Network. For commercial reprints, please contact the official authorization. For non-commercial reprints, please indicate the source.
Option One:
/*
* @lc app=leetcode.cn id=142 lang=javascript
*
* [142] 环形链表 II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if(!head) return null;
let hash = new Map();
while(head) {
if(hash.has(head)) return head;
hash.set(head);
head = head.next;
}
return null;
};
Option II:
/*
* @lc app=leetcode.cn id=142 lang=javascript
*
* [142] 环形链表 II
*/
// @lc code=start
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if (head === null) {
return null;
}
let slow = head, fast = head;
while (fast !== null) {
slow = slow.next;
if (fast.next !== null) {
fast = fast.next.next;
} else {
return null;
}
if (fast === slow) {
let ptr = head;
while (ptr !== slow) {
ptr = ptr.next;
slow = slow.next;
}
return ptr;
}
}
return null;
};
There are two solutions: 1. Use map or set data structure to record the linked list, and the space complexity is O(N); 2.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。