1.动态规划
1.1 返回方案数/组合数
排列数(顺序不同也是新的一种方案)
var combinationSum4 = function(nums, target) {
let dp=new Array(target+1).fill(0)
dp[0]=1
for(let i=1;i<=target;i++){
for(let j=0;j<nums.length;j++){
if(i-nums[j]>=0){
dp[i]+=dp[i-nums[j]]
}
}
}
return dp[target]
};
组合数(顺序不同也是同一种方案)
var change = function(amount, coins) {
const dp = new Array(amount + 1).fill(0);
dp[0] = 1;
for (const coin of coins) {
//
for (let i = coin; i <= amount; i++) {
dp[i] += dp[i - coin];
}
}
return dp[amount];
};
如果求组合数就是外层for循环遍历数组,内层for遍历目标值,内层要倒着遍历。
如果求排列数就是外层for遍历目标值,内层for循环遍历数组。
1.2 返回可能的具体方案/组合
这种一般都是回溯+剪枝。并不算动态规划,放这里是区分不同情况,防止该回溯的时候用动态规划。
/**
* @param {number[]} candidates
* @param {number} target
* @return {number[][]}
*/
var combinationSum = function(candidates, target) {
const res=[]
var dfs=function(index,target,arr){
if(target===0){
res.push([...arr])
return
}
for(let i=index;i<candidates.length;i++){
if(target-candidates[i]>=0){
dfs(i,target-candidates[i],[...arr,candidates[i]])
}
}
}
dfs(0,target,[])
return res
};
2.排序
2.1 堆排序
堆排序首先建堆,建堆从下往上、从右往左调整,每调整一个父子组合,都要看有没有影响下面的,再向下调整。调整完继续从下往上、从右往左调整。 然后最大的就被放到了数组第一位,与最后一位交换。交换后是从上向下调整一遍就行了,注意这次调整不能再调整数组最后一位了,这是易错点,调整上界要不断减少。
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var findKthLargest = function(nums, k) {
heapSort(nums)
return nums[nums.length-k]
//堆排序
function heapSort(nums){
let count=1
//建堆
heapBuild(nums)
while(count<=k){
//交换并从上向下调整
swap(nums,0,nums.length-count)
count++
justify(nums,0,nums.length-count)
}
}
//建大根堆
function heapBuild(nums){
// 从最后一个非叶结点从右向左,从下向上调整
for(let i=Math.floor((nums.length-1)/2);i>=0;i--){
justify(nums,i,nums.length-1)
}
}
//调整堆,选出左右孩子最大的与之交换,注意heapSize是调整堆的最大下标
function justify(arr,start,heapSize){
let left=2*start+1
let right=2*start+2
let largest=start
if(left<=heapSize && arr[left]>arr[largest]){
largest=left
}
if(right<=heapSize && arr[right]>arr[largest]){
largest=right
}
if(largest!=start){
swap(arr,largest,start)
//交换以后引起下面不满足大根堆条件,继续递归调整
justify(arr,largest,heapSize)
}
}
function swap(arr,i,j){
let temp=arr[i]
arr[i]=arr[j]
arr[j]=temp
}
};
2.2 快速排序
function partition(arr,start,end){
if(start<=end){
return
}
let target=arr[start]
let low=start,high=end
while(low<high){
while(low<high && arr[high]>=target){
high--
}
arr[low]=arr[high]
while(low<high && arr[low]<=target){
low++
}
arr[high]=arr[low]
}
arr[low]=target
partition(arr,start,low-1)
partition(arr,low+1,end)
}
function quickSort(nums){
partition(nums,0,nums.length-1)
}