计数排序
- 统计每一项出现的次数
- 根据统计的次数循环输出对应的值
- 应用于值域有限的排序场景中
基数排序
- 统计低16位每个数字出现的次数,求其前缀和后在temp里排序
- 统计高16位每个数字出现的次数,求其前缀和后将temp的数在原数组排序
- 基数排序是利用前两步排序的数据之间的稳定性实现最终排序效果
拓扑排序
- 统计所有元素的入度和对应关系,将入度为0的元素入队
- 队列每出队一个元素,将指向的元素入度减一,若该元素入度为0则入队
- 队列弹出元素即是拓扑序列
LeetCode肝题
-
- 数组的相对排序
var relativeSortArray = function(arr1, arr2) {
let cut = new Array(1001).fill(0)
for(let i of arr1) cut[i]++
let k = 0
for(let i = 0; i < arr2.length; i++) {
for(let j = 0; j < cut[arr2[i]]; j++) {
arr1[k++] = arr2[i]
}
cut[arr2[i]] = 0
}
for(let i in cut) {
if (cut[i] == 0) continue
for(let j = 0; j < cut[i]; j++) arr1[k++] = i
}
return arr1
};
-
- 最大间距
var maximumGap = function(nums) {
if (nums.length < 2) return 0
let cut = new Array(65536).fill(0), temp = new Array(nums.length).fill(0)
for(let i of nums) cut[i % 65536] += 1
for(let i = 1; i < cut.length; i++) cut[i] += cut[i - 1]
for(let i = nums.length - 1; i >=0 ; --i) temp[--cut[nums[i] % 65536]] = nums[i]
cut.fill(0)
for(let i of temp) cut[parseInt(i / 65536)] += 1
for(let i = 1; i < 65536; i++) cut[i] += cut[i - 1]
for(let i = temp.length - 1; i >= 0; --i) nums[--cut[parseInt(temp[i] / 65536)]] = temp[i]
let ans = 0
for(let i = 1; i < nums.length; i++) {
ans = Math.max(ans, nums[i] - nums[i - 1])
}
return ans
};
-
- H 指数
var hIndex = function(citations) {
citations = citations.sort((a,b) => a - b)
let h = 1, len = citations.length
while(h <= len && citations[len - h] >= h) ++h
return h-1
};
-
- 课程表
var canFinish = function(numCourses, prerequisites) {
let indeg = Array(numCourses).fill(0), g = Array(numCourses), q = [], cut = 0
for(let i = 0; i < g.length; i++) g[i] = []
for(let item of prerequisites) {
indeg[item[0]] += 1
g[item[1]].push(item[0])
}
for(let i = 0; i < indeg.length; i++) {
if (indeg[i] == 0) q.push(i)
}
while(q.length > 0) {
let top = q.shift()
cut++
for(let i of g[top]) {
indeg[i] -= 1
if (indeg[i] == 0) q.push(i)
}
}
return cut == numCourses
};
-
- 课程表 II
var findOrder = function(numCourses, prerequisites) {
let indeg = Array(numCourses).fill(0), g = Array(numCourses), q = [], ans = []
for(let i = 0; i < g.length; i++) g[i] = []
for(let item of prerequisites) {
indeg[item[0]] += 1
g[item[1]].push(item[0])
}
for(let i = 0; i < indeg.length; i++) {
if (indeg[i] == 0) q.push(i)
}
while(q.length > 0) {
let top = q.shift()
ans.push(top)
for(let i of g[top]) {
indeg[i] -= 1
if (indeg[i] == 0) q.push(i)
}
}
return ans.length == numCourses ? ans : []
};
-
- 合并区间
var merge = function(intervals) {
intervals = intervals.sort((a, b) => a[0] - b[0])
let ans = [intervals[0]]
for(let i = 1; i < intervals.length; i++) {
let len = ans.length - 1
if (intervals[i][0] <= ans[len][1] && intervals[i][1] > ans[len][1]) {
ans[len][1] = intervals[i][1]
}
if (intervals[i][0] > ans[len][1]) {
ans.push(intervals[i])
}
}
return ans
};
-
- 删除被覆盖区间
var removeCoveredIntervals = function(intervals) {
intervals = intervals.sort((a, b) => {
if (a[0] == b[0]) return b[1] - a[1]
return a[0] - b[0]
})
let ans = [intervals[0]]
for(let i = 1; i < intervals.length; i++) {
let len = ans.length - 1
if(intervals[i][0] >= ans[len][0] && intervals[i][1] <= ans[len][1]) {
continue
}
ans.push(intervals[i])
}
return ans.length
};
- 491.递增子序列
var getResult = function(nums, k, buff, ans) {
if (buff.length > 1) ans.push(JSON.parse(JSON.stringify(buff)))
buff.push(0)
let map = {}
for(let i = k; i < nums.length; i++) {
if (map[nums[i]]) continue
if (buff.length == 1 || nums[i] >= buff[buff.length - 2]) {
buff[buff.length - 1] = nums[i]
map[nums[i]] = 1
getResult(nums, i + 1, buff, ans)
buff.pop()
}
}
}
var findSubsequences = function(nums) {
let ans = []
getResult(nums, 0, [], ans)
return ans
};
- 面试题 04.12. 求和路径
var getPathSum = function(root, sum) {
if(!root) return 0
const val = sum - root.val, a = root.val == sum ? 1 : 0
return a + getPathSum(root.left, val) + getPathSum(root.right, val)
}
var pathSum = function(root, sum) {
if (!root) return 0
return getPathSum(root, sum) + pathSum(root.left, sum) + pathSum(root.right, sum)
};