反转链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
输入: head = [1,2,3,4,5]
输出: [5,4,3,2,1]
- 迭代法
/**
* 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) {
var pre = null
var curr = head
while (head) {
curr = head;
head = head.next
curr.next = pre
pre = curr
}
return curr
};
- 递归法
/**
* 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 || !head.next) return head
var newHead = reverseList(head.next)
var next = head.next head.next.next = head
head.next = null
return newHead
};
链表相交
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。
图示两个链表在节点 c1 开始相交:
- 双指针
/**
* 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) {
var A = headA;
var B = headB;
while(A !== B){
A = A === null ? headB : A.next;
B = B === null ? headA : B.next;
}
return A
};
- 双循环
/**
* 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) {
var cloneA = headA
var cloneB = headB
while(cloneA){
while(cloneB){
if(cloneA === cloneB){
return cloneB
}
cloneB = cloneB.next
}
cloneA = cloneA.next
cloneB = headB
}
return null
};
- 利用高阶函数
/**
* 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) {
var lastA = headA
var lastB = headB
var valArr = []
while(lastA){
valArr.push(lastA)
lastA = lastA.next
}
while(lastB){
if(valArr.includes(lastB)) return lastB
lastB = lastB.next
}
return null
};
旋转链表
给你一个链表的头节点 head
,旋转链表,将链表每个节点向右移动 k
个位置。
输入: head = [1,2,3,4,5], k = 2
输出: [4,5,1,2,3]
- 利用数组
/**
* 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 arr = []
var cloneHead = head
while (cloneHead) {
arr.push(cloneHead)
cloneHead = cloneHead.next
}
var len = arr.length
if (k > len) {
k = k % len
}
if (!head || k === 0 || len === 1 || len === k) {
return head
}
var newHead = arr[len - k]
arr[len - k - 1].next = null
arr[len - 1].next = arr[0]
return newHead
};
- 闭合为环
/**
* 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 (k === 0 || !head || !head.next) {
return head;
}
let n = 1;
let cur = head;
while (cur.next) {
cur = cur.next;
n++;
}
let add = n - k % n;
if (add === n) {
return head;
}
cur.next = head;
while (add) {
cur = cur.next;
add--;
}
const ret = cur.next;
cur.next = null;
return ret;
};
数据流中的第 K 大元素
设计一个找到数据流中第 k 大元素的类(class)。注意是排序后的第 k 大元素,不是第 k 个不同的元素。
请实现 KthLargest 类:
KthLargest(int k, int[] nums) 使用整数 k 和整数流 nums 初始化对象。 int add(int val) 将 val 插入数据流 nums 后,返回当前数据流中第 k 大的元素。
输入:
["KthLargest", "add", "add", "add", "add", "add"]
[[3, [4, 5, 8, 2]], [3], [5], [10], [9], [4]]
输出:
[null, 4, 5, 5, 8, 8]
解释:
KthLargest kthLargest = new KthLargest(3, [4, 5, 8, 2]);
kthLargest.add(3); // return 4
kthLargest.add(5); // return 5
kthLargest.add(10); // return 5
kthLargest.add(9); // return 8
kthLargest.add(4); // return 8
- 按顺序放入数组中,直接拿出第K大的值
/**
* @param {number} k
* @param {number[]} nums
*/
var KthLargest = function(k, nums) {
this.k = k
this.valArr = nums.sort((a, b) => b - a) || []
};
/**
* @param {number} val
* @return {number}
*/
KthLargest.prototype.add = function(val) {
var len = this.valArr.length
if (len === 0) {
this.valArr.push(val)
return this.valArr[this.k - 1]
}
if (val >= this.valArr[0]) {
this.valArr.unshift(val)
return this.valArr[this.k - 1]
}
if (val <= this.valArr[len - 1]) {
this.valArr.push(val)
return this.valArr[this.k - 1]
}
if (len === 2) {
this.valArr.splice(1, 0, val)
return this.valArr[this.k - 1]
}
var start = 0;
var end = len - 1;
var flag = true;
while (flag) {
var middle = (end + start) >> 1
var pre = this.valArr[middle - 1]
var next = this.valArr[middle + 1]
if (this.valArr[middle] >= val) {
if (val >= next) {
this.valArr.splice(middle + 1, 0, val)
flag = false
break
}
}
if (val >= this.valArr[middle]) {
if (pre >= val) {
this.valArr.splice(middle, 0, val)
flag = false
break
}
}
if (this.valArr[middle] < val) {
end = middle
}
if (this.valArr[middle] > val) {
start = middle
}
}
return this.valArr[this.k - 1]
};
翻转二叉树
翻转一棵二叉树。
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
- 递归法
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
if(!root) return root
let temp = root.left
root.left = root.right
root.right = temp
invertTree(root.left)
invertTree(root.right)
return root
};
- 深度优先遍历
var invertTree = function(root) {
if(!root) return root
var stack = []
stack.push(root)
while(stack.length>0){
var node = stack.pop();
var temp = node.left
node.left = node.right
node.right = temp
if(node.right) stack.push(node.right)
if(node.left) stack.push(node.left)
}
return root
};
- 层序遍历
var invertTree = function(root) {
if(!root) return root
var queue = []
queue.push(root)
while(queue.length>0){
var node = queue.shift();
var temp = node.left
node.left = node.right
node.right = temp
if(node.right) queue.push(node.right)
if(node.left) queue.push(node.left)
}
return root
};