算法题(附答案)

排列组合

    1. 全排列,无顺序要求
    1. 全排列,取前n项
    1. 全排列,数字重复
    1. 全排列,有序,取第n项
    1. 全排列,无重复数字
    1. 全排列,有序,取第n项
  • 问题 1-6,可通过对数组进行有序全排列解决
let array = [1, 2, 3]
let res = []
// 回溯
function ds(initArray) {   
    if (initArray.length === array.length) {
        return res.push(initArray)
    }
    for (let i = 0; i < array.length; i++) {
        if (initArray.includes(array[i])) continue
        initArray.push(array[i])
        ds([...initArray])
        initArray.pop()
    }
} 
ds([])
console.log(res)

或

let array = [1, 2, 3]
let res = []

function ds(initArray, array) {
    if (!array.length) {
        return res.push(initArray)
    }
    for (let i = 0; i < array.length; i++) {
        if (i > 0 && array[i] === array[i - 1]) continue
        const newArray = JSON.parse(JSON.stringify(array))
        newArray.splice(i, 1)
        ds(initArray.concat(array[i]), newArray)
    }
}
ds([], array)
console.log(res)
    1. 全排列,求和,数字可重复选取
    1. 全排列,求和,数字只能用一次
  • 问题 7-8,回溯剪枝
let array = [2, 4, 6, 8]
let target = 8

let res = []

function ds(target, index, path) {
    if (target === 0) {
        return res.push([...path])
    }
    if (target > 0 && index < array.length) {
        for (let i = index; i < array.length; i++) {
            if (target < array[i]) return
            target -= array[i]
            path.push(array[i])
            ds(target, i, path)   // 允许选择数字重复
            // ds(target, i + 1, path)   不允许选择数字重复
            target += array[i]
            path.pop()
        }
    }
}
ds(target, 0, [])
console.log(res)
    1. 全排列,求和,动态参数
    1. 回文排列

二分查找

// 思路 : 
1. 二分取中位数与最右值相比,若大于则左侧有序,否则右侧有序 
2. 使用有序一侧最大和最小值与target进行比较确定范围
3. 更改left或right值为中值向左或右移动
var search = function (nums, target) {
    function ds(left, right) {
        while (left <= right) {
        let mid = left + right >> 1
        if (nums[mid] === target) {
            return mid
        }
        if (nums[mid] > nums[right]) {
            if (nums[left] <= target && target < nums[mid]) {
            right = mid - 1
            } else {
            left = mid + 1
            }
        } else {
            if (nums[mid] < target && target <= nums[right]) {
            left = mid + 1
            } else {
            right = mid - 1
            }
        }
        }
        return -1
    }
    return ds(0, nums.length-1)
};
// 二分查找
let nums = [5, 7, 7, 8, 8, 10], target = 8

function ds(left, right) {
    let mid = left + right >> 1
    if (target > nums[mid]) {
        return ds(mid + 1, right)
    } else if (target < nums[mid]) {
        return ds(left, mid - 1)
    } else {
        let start = mid
        let end = mid
        while (nums[end + 1] === nums[mid]) {
            end++
        }
        while (nums[start - 1] === nums[mid]) {
            start--
        }
        return [start, end]
    }
}

console.log(ds(0, nums.length - 1))
  • 最长递增子序列
// 动态规划
var lengthOfLIS = function (nums) {
    let res = 1
    let d = new Array(nums.length).fill(1)

    for (let i = 1; i < nums.length; i++) {
        for (let j = 0; j < i; j++) {
            if (nums[i] > nums[j]) {
                d[i] = Math.max(d[i], d[j] + 1)
            }
        }
        res = Math.max(res, d[i])
    }
    return res
};
let nums = [10, 9, 2, 5, 3, 7, 101, 18]
console.log(lengthOfLIS(nums))
双指针法
let str = 'cvfddssssds'
let res = str.charAt(0)
let last = str.charAt(0)
let count = 1
for (let i = 1; i < str.length; i++) {
    if (last === str.charAt(i)) {
        count++
    } else {
        res += count
        res += str.charAt(i)
        last = str.charAt(i)
        count = 1
    }
}
if (count !== 0) {
    res += count
}
console.log(res)
var validPalindrome = function(s) {
    let i = 0
    let j =s.length-1
    if(flag(s,i,j)){
        return true
    }
    
    while(i<=j){
        if(s.charAt(i)!=s.charAt(j)){ 
            str1 = s.slice(0,i)+''+s.slice(i+1)
            str2 = s.slice(0,j)+''+s.slice(j+1) 
            return flag(str1,0,s.length-2) || flag(str2,0,s.length-2)
        }else{
            i++
            j--
        }
    }
    function flag(s,l,r){
        while(l<=r){
            if(s.charAt(l) != s.charAt(r)){
                return false
            }else{
                l++
                r--
            }
        }
        return true
    }
};
let s = 'abcd'
let t = 'ahbgdc'

let index = 0
let res = ''

for (let i = 0; i < s.length; i++) {
    for (let j = index; j < t.length; j++) {
        if (t.charAt(j) === s.charAt(i)) {
            res += t.charAt(j)
            index = j + 1
            break;
        }
    }
}
console.log(s === res)
let nums = [0, 0, 1, 1, 1, 2, 2, 3, 3, 4,5,6,7]
let last = nums[0]
for (let i = 1; i < nums.length; i++) {
    if (nums[i] === last) {
        nums.splice(i, 1)
        i--
    } else {
        last = nums[i]
    }
}
console.log(nums, nums.length)
let nums = [-1, 0, 1, 2, -1, -4]
nums.sort((a, b) => a - b)
let res = []
for (let i = 0; i < nums.length; i++) {
    let start = i + 1
    let end = nums.length - 1
    
    while (start < end) {
        if (nums[i] + nums[start] + nums[end] === 0) {
            res.push([nums[i], nums[start], nums[end]])
            break;
        } else if (nums[i] + nums[start] + nums[end] > 0) {
            end--
        } else {
            start++
        }
    }
}
console.log(res)
let nums = [1, 0, -1, 0, -2, 2]
let res = []
nums.sort((a, b) => a - b)
for (let i = 0; i < nums.length - 3; i++) {
    if (i > 0 && nums[i] === nums[i - 1]) {
        continue
    }
    for (let j = i + 1; j < nums.length - 2; j++) {
        if (nums[j] === nums[j - 1]) {
            continue
        }
        if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > 0) {
            break;
        }
        let start = j + 1
        let end = nums.length - 1
        while (nums[start] === nums[1 + start]) {
            start++
        }
        while (nums[end] === nums[end - 1]) {
            end--
        }
        while (start < end) {
            if (nums[start] + nums[end] + nums[i] + nums[j] === 0) {
                res.push([nums[start], nums[end], nums[i], nums[j]])
                break;
            } else if (nums[start] + nums[end] + nums[i] + nums[j] > 0) {
                end--

            } else {
                start++

            }
        }
    }
}

console.log(res)
贪心算法
树的遍历
function recursion(root) {
    if (!root) return
 // outArray.push(root.val) //  前序遍历
    recursion(root.left)
 // outArray.push(root.val) //  中序遍历
    recursion(root.right)
    outArray.push(root.val) //  后序遍历
}
// 执行递归
recursion(root) 
广度、深度优先
var levelOrder = function(root) {
    if(root == null){
        return []
    }
    let queue = []
    let res = []
    queue.push(root)
    while(queue.length > 0){
        let arr = []
        let n = queue.length 
        for(let i=0;i<n;i++){
            let ele = queue.shift()
            arr.push(ele.val) 
            if(ele.left){
                queue.push(ele.left)
            }
            if(ele.right){
                queue.push(ele.right)
            }
        }
        res.push(arr)
    }
    return res
};  
var levelOrderBottom = function(root) {
    if(root == null){
        return []
    }
    let res = []
    let queue = []
    queue.push(root)
    while(queue.length > 0){
        let arr = []
        let  n = queue.length
        for(let i=0;i<n;i++){
            let ele = queue.shift()
            arr.push(ele.val)
            if(ele.left){
                queue.push(ele.left)
            }
            if(ele.right){
                queue.push(ele.right)
            }
        }
        res.push(arr)
    }
    return res.reverse()
};
var levelOrder = function(root) { 
    if(!root){
        return []
    }
    let res = []
    let queue = []
    queue.push(root) 
    while(queue.length>0){ 
        let arr = []  
        let n = queue.length
        for(let j=0;j<n;j++){ 
            let cur = queue.shift() 
            arr.push(cur.val)
            for(let i=0;i<cur.children.length;i++){
                queue.push(cur.children[i])
            } 
        }  
        res.push(arr)
    }
    return res
    
};
function recursion(root) {
    if (!root) return 
    recursion(root.left)
    outArray.push(root.val) //  中序遍历
    recursion(root.right) 
}
console.log(recursion(root)[k-1])
var minDepth = function(root) {
    if(!root){
        return 0 
    }
    let queue = []
    queue.push(root) 
    let height = 1
    while(queue.length>0){
        let n = queue.length 
        for(let i=0;i<n;i++){
            let cur = queue.shift() 
            if(cur.left){
                queue.push(cur.left)
            }
            if(cur.right){
                queue.push(cur.right)
            }
            if(!cur.left && !cur.right){
                return height
            }   
        }
        height++ 
    }
};
var maxDepth = function(root) {
    if(root == null){
        return []
    }
    let res =  []
    let queue  = []
    let count = 0
    queue.push(root)
    while(queue.length >  0){
        let n = queue.length
        let arr = []
        for(let i=0;i<n;i++){
            let ele = queue.shift()
            arr.push(ele.val)
            if(ele.left){
                queue.push(ele.left)
            }
            if(ele.right){
                queue.push(ele.right)
            } 
        }
        count++
    }
    return count
};
动态规划
var uniquePaths = function(m, n) { 
    let min = m>n?n:m
    let max = m<n?n:m
    let array = [] 
    for(let i=0;i<min;i++){
        array[i] = []
    }
    array[0][0] = 0
    for(let i=0;i<min;i++){
        array[i][0] = 1
    }
    for(let i=0;i<max;i++){
        array[0][i] = 1
    }
    for(let i=1;i<min;i++){
        for(let j=1;j<max;j++){
            array[i][j] = array[i-1][j] + array[i][j-1]
        }
    }
    return array[min-1][max-1]
};
var climbStairs = function (n) {
  if (n === 0) { return 0 }
  if (n === 1) { return 1 }
  if (n === 2) { return 2 }
  let res = [0, 1, 2]
  for (let i = 3; i <= n; i++) {
    res.push(res[i - 2] + res[i - 1])
  }
  return res[n]
};

var climbStairs = function (n) {
  function f(n) {
    if (n === 0) return 0
    if (n === 1) return 1
    if (n === 2) return 2
    return f(n - 1) + f(n - 2)
  }
  return f(n)
};
数学技巧
var mySqrt = function(x) {
    for(let i=1;i<=Math.ceil(x/2)+1;i++){
        if(i * i >x){
            return i-1
        }
    }
};
var missingNumber = function(nums) {
    if(nums.length == 0){
        return 0
    }
    let max = nums[0]
    for(let i=1;i<nums.length;i++){
        if(max < nums[i]){
            max = nums[i]
        }
    }
    let array = []
    for(let i=0;i<=max;i++){
        let arr = new Array()
        array.push(arr)
    }
    for(let i=0;i<nums.length;i++){
        if(array[nums[i]]){
            array[nums[i]].push(nums[i])
        } 
    } 
    for(let i=0;i<=array.length;i++){
        if(i==array.length || array[i].length==0){ 
            return i
        }
    }
};
var isPowerOfTwo = function(n) {
    let i=0
    while(Math.pow(2,i)<n){
        i++
    }
    return Math.pow(2,i) == n
};
var isPowerOfThree = function(n) {
    let i=0
    while(Math.pow(3,i) <= n){
        i++
    }
    return Math.pow(3,i-1) == n
};
var countNumbersWithUniqueDigits = function(n) {
    if(n==0){
        return 1
    }else if(n==1){
        return 10
    }else{
        let sum = 9
        for(let i=0;i<n-1;i++){
            sum *= 9 - i
        } 
        return countNumbersWithUniqueDigits(n-1) + sum
    } 
};
var fib = function(n) {
    if(n ==0){
        return 0
    }else if(n <= 2){
        return 1
    }else {
        return fib(n-1) + fib(n-2)
    }
};
回溯
var letterCombinations = function(digits) {
    let arr =['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    let res = []
    function dfs(count, prev){
        if(count==digits.length){
            res.push(prev)
            return 
        }
        let curStr = arr[digits.charAt(count)]
        for(let i=0;i<curStr.length;i++){
            dfs(count+1,prev+curStr.charAt(i))
        }
    }
    if(digits.length>0){
        dfs(0,'')
    }
    return res
};
var generateParenthesis = function(n) {
    let res = []
    function back(prev, count, number){
        if(count==0){
            res.push(prev+new Array(number).fill(')').join(""))
            return 
        }
        if(count !== number){ 
            back(prev+')',count,number-1)
        }
        back(prev+'(',count-1,number)
    }
    if(n>0){
        back('(', n-1,n)
    }
    return res
};
var partition = function(s) {
    let res = []
    let left = 0
    let right = 0
    back(left, right, [])
    function back(left, right, arr){
        if(left == s.length){
            return res.push([...arr])
        }
        for(let i = right;i<s.length;i++){
            if(flag(s,left,i)){
                arr.push(s.slice(left,i+1))
                back(i+1,i+1,arr)
                arr.pop()
            }
        }
    }
    function flag(s,l,r){
        while(l<r){
            if(s.charAt(l) == s.charAt(r)){
                l++
                r--
            }else{
                return false
            }
        }
        return true
    }
    return res
};

背包

最小路径
背包问题
股票问题
区间问题

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,999评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,102评论 1 302
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,709评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,439评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,846评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,881评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,062评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,783评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,517评论 1 248
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,762评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,241评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,236评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,145评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,941评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,965评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,802评论 2 275

推荐阅读更多精彩内容