归并排序
- 处理左边 得到左边的信息
- 处理右边 得到右边的信息
- 完成合并过程 得到横跨两边的信息
手撕归并排序
function merge_sort(arr, l, r) {
if (l >= r) return
let mid = (l + r) >> 1
merge_sort(arr, l, mid)
merge_sort(arr, mid + 1, r)
let temp = Array(r - l + 1), k = 0, p1 = l, p2 = mid + 1
while (p1 <= mid || p2 <= r) {
if (p2 > r || (p1 <= mid && arr[p1] <= arr[p2])) {
temp[k++] = arr[p1++]
} else {
temp[k++] = arr[p2++]
}
}
for(let i = l; i <= r; i++) arr[i] = temp[i - l]
}
LeetCode肝题
- 剑指 Offer 51. 数组中的逆序对
var temp = []
var countReversePairs = function(nums, l, r) {
if (l >= r) return 0;
let mid = (l + r) >> 1, ans = 0;
ans += countReversePairs(nums, l, mid);
ans += countReversePairs(nums, mid + 1, r);
let k = l, p1 = l, p2 = mid + 1;
while((p1 <= mid) || (p2 <= r)) {
if ((p2 > r) || (p1 <= mid && nums[p1] <= nums[p2])) {
temp[k++] = nums[p1++]
} else {
temp[k++] = nums[p2++]
ans += (mid - p1 + 1)
}
}
for(let i = l; i <= r; i++) nums[i] = temp[i]
return ans
}
var reversePairs = function(nums) {
while (temp.length < nums.size) temp.push(0);
return countReversePairs(nums, 0, nums.length - 1)
};
-
- 合并K个升序链表
var mergeKLists = function(lists) {
let q = new MinPriorityQueue({priority: p => p.val}), ret = new ListNode()
for (let i = 0; i < lists.length; i++) {
if (!lists[i]) continue
q.enqueue(lists[i])
}
let p = ret
while(!q.isEmpty()) {
let top = q.dequeue()
if (top.element.next) q.enqueue(top.element.next)
p.next = top.element
p = p.next
}
return ret.next
};
-
- 排序链表
var mergeSort = function(head, n) {
if (!head || !head.next) return head;
let l = n >> 1, r = n - l;
let lp = head, rp = lp, p
for (let i = 1; i < l; i ++) rp = rp.next
p = rp
rp = rp.next
p.next = null
lp = mergeSort(lp, l)
rp = mergeSort(rp, r)
let ret = new ListNode()
p = ret
while(lp || rp) {
if (rp == null || (lp && lp.val <= rp.val)) {
p.next = lp
lp = lp.next
p = p.next
} else {
p.next = rp
rp = rp.next
p = p.next
}
}
return ret.next;
}
var sortList = function(head) {
let n = 0, p = head;
while (p) {
n += 1
p = p.next;
}
return mergeSort(head, n);
};
-
- 两棵二叉搜索树中的所有元素
var sortTree = function(root, arr) {
if (!root) return []
root.left && sortTree(root.left, arr)
arr.push(root.val)
root.right && sortTree(root.right, arr)
return arr
}
var getAllElements = function(root1, root2) {
let arr_left = sortTree(root1, []), arr_right = sortTree(root2, [])
let i = 0, j = 0, ans = []
while(i < arr_left.length || j < arr_right.length) {
if (j >= arr_right.length || (i < arr_left.length && arr_left[i] <= arr_right[j])) {
ans.push(arr_left[i])
i++
} else {
ans.push(arr_right[j])
j++
}
}
return ans
};
-
- 区间和的个数
var countTwoPart = function(sum, l1, r1, l2, r2, lower, upper) {
let ans = 0, k1 = l1, k2 = l1
for(let j = l2; j <= r2; j++) {
let a = sum[j] - upper
let b = sum[j] - lower
while(k1 <= r1 && sum[k1] < a) k1 += 1
while(k2 <= r1 && sum[k2] <= b) k2 += 1
ans += k2 - k1
}
return ans
}
var margeSort = function(sum, l, r, lower, upper) {
if (l >= r) return 0
let mid = (l + r) >> 1, ans = 0
ans += margeSort(sum, l, mid, lower, upper)
ans += margeSort(sum, mid + 1, r, lower, upper)
ans += countTwoPart(sum, l, mid, mid + 1, r, lower, upper)
let k = l, p1 = l, p2 = mid + 1
while(p1 <= mid || p2 <= r) {
if (p2 > r || (p1 <= mid && sum[p1] <= sum[p2])) {
temp[k++] = sum[p1++]
} else {
temp[k++] = sum[p2++]
}
}
for(let i = l; i <= r; i++) sum[i] = temp[i]
return ans
}
let temp
var countRangeSum = function(nums, lower, upper) {
let sum = Array(nums.length + 1)
temp = Array(nums.length + 1).fill(0)
sum[0] = 0
for (let i = 0; i < nums.length; i++) sum[i + 1] = nums[i] + sum[i]
return margeSort(sum, 0, sum.length - 1, lower, upper)
};
-
- 最大子序和
var maxSubArray = function(nums) {
let sum = [0], pre = 0
for (let i = 0; i < nums.length; i++) sum.push(nums[i] + sum[i])
let ans = sum[1]
for (let i = 1; i < sum.length; i++) {
ans = Math.max(sum[i] - pre, ans)
pre = Math.min(sum[i], pre)
}
return ans
};
-
- 子数组和排序后的区间和
var rangeSum = function(nums, n, left, right) {
let q = new MinPriorityQueue({priority: p => p.sum})
for (let i = 0; i < n; i++) {
q.enqueue({i: i, j: i, sum: nums[i]})
}
let ans = 0, mod = 1000000000+7
for (let i = 0; i < right; i++) {
let top = q.dequeue().element
if (top.j < n - 1) q.enqueue({i: top.i, j: top.j + 1, sum: top.sum + nums[top.j + 1]})
if (i >= left - 1) ans += top.sum
}
return ans % mod
};
- 面试题 04.08. 首个共同祖先
var lowestCommonAncestor = function(root, p, q) {
if (!root) return root
if (root == p || root == q) return root
let l = lowestCommonAncestor(root.left, p, q), r = lowestCommonAncestor(root.right, p, q)
if (l && r) return root
if (l) return l
return r
};
-
- 层数最深叶子节点的和
function getResult(root, k, result) {
if (!root) return
if (k == result.max_k) result.ans += root.val
if (k > result.max_k) {
result.max_k = k
result.ans = root.val
}
getResult(root.left, k + 1, result)
getResult(root.right, k + 1, result)
return
}
var deepestLeavesSum = function(root) {
let result = {
max_k: 0,
ans: 0
}
getResult(root, 1, result)
return result.ans
};