算法刷题——递归回溯

135 阅读1分钟

面试题 16.11 跳水板

/**
 * @param {number} shorter
 * @param {number} longer
 * @param {number} k
 * @return {number[]}
 */
var divingBoard = function(shorter, longer, k) {
    let res = [];
    if(k === 0)
        return res;
    if(shorter === longer)
        return [k * shorter];
    
    for(let i = 0; i <= k; i++){
        res.push(longer * i + shorter *(k - i));
    }
    return res;
};

257 二叉树所有路径

17电话号码的字母组合

leetcode-cn.com/problems/le…

/**
 * @param {string} digits
 * @return {string[]}
 */
var letterCombinations = function(digits) {
    if(digits.length === 0)
        return [];
    let reflect = {
        '2':['a','b','c'],'3':['d','e','f'],'4':['g','h','i'],'5':['j','k','l'],
        '6':['m','n','o'],'7':['p','q','r','s'],'8':['t','u','v'],'9':['w','x','y','z']
    }
    let res = [];
    function dfs(index,str){
        if(index === digits.length)
        {
            res.push(str);
            return;
        }
        let dig = digits[index];
        let digArr = reflect[dig];
        for(let i = 0; i < digArr.length; i++){
            dfs(index + 1, str+digArr[i]);
        }
    }
    dfs(0,'');
    return res;
};

131 分割回文串

leetcode-cn.com/problems/pa…

/**
 * @param {string} s
 * @return {string[][]}
 */
var partition = function(s) {
    if(s.length === 0)
        return [];
    let res = [];
    dfs(0,s,res,[]);

    return res;
};
//开始分割的地方  源字符串  结果集  这一次的分割结果
function dfs(start, s, res, curArr){
    if(start === s.length)
    {
        res.push(curArr.slice(0));
        return ;
    }

    for(let i = start; i < s.length; i++){
        let subStr = s.slice(start,i + 1);//分割的时候至少包括一个s[start]
        if(subStr && isHuiWen(subStr)){
            dfs(i + 1, s, res, [...curArr,subStr]);//不改变curArr以便其他的分割进行使用。
        }
    }
    return ;
}

//str是不是回文子串
function isHuiWen(str){
    let left = 0;
    let right = str.length - 1;
    while(left <= right){
        if(str[left] !== str[right]){
            return false;
        }
        left++;
        right--;
    }
    return true;
}

60 第K个排列

77 组合

leetcode-cn.com/problems/co…

/**
 * @param {number} n
 * @param {number} k
 * @return {number[][]}
 */
var combine = function(n, k) {
    let res = [];

    const dfs = (temp,index) =>{
        if(temp.length === k){
            res.push([...temp]);
            return;
        }
        for(let i = index; i <= n ; i++){//平级时忽略前面的
            temp.push(i);
            dfs(temp,i + 1);
            temp.pop();
        }
        return;
    }
    dfs([],1);
    return res;
};

39 组合总和

leetcode-cn.com/problems/co…

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum = function(candidates, target) {
    let res = [];

    const dfs = (temp,tempSum,index) => {
        if(tempSum === target){
            res.push([...temp]);
            return;
        }
        for(let i = index; i < candidates.length; i++){
            if(tempSum + candidates[i] <= target){
                temp.push(candidates[i]);
                dfs(temp,tempSum + candidates[i], i);//同级时从当前开始遍历
                temp.pop();
            }
        }
        return;
    }

    dfs([],0,0);

    return res;
};

40 组合总和2

leetcode-cn.com/problems/co…

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum2 = function(candidates, target) {
    let res = [];
    candidates.sort((a,b)=>(a-b));//升序排序

    const dfs = (temp, tempSum, index) => {
        if(tempSum === target){
            res.push([...temp]);
            return;
        }
        for(let i = index; i < candidates.length; i++){
            //在平级的时候,如果当前数和前一个数一样就直接跳过
            if(i - 1 >= index && candidates[i] === candidates[i - 1]) continue;

            if(tempSum + candidates[i] <= target){
                temp.push(candidates[i]);
                dfs(temp, tempSum + candidates[i], i + 1);//保证深度遍历的时候取的索引不重复
                temp.pop();
            }
        }
        return ;
    }
    dfs([], 0, 0);

    return res;
};

216 组合总和3

leetcode-cn.com/problems/co…

/**
 * @param {number} k
 * @param {number} n
 * @return {number[][]}
 */
var combinationSum3 = function(k, n) {
    let res = [];

    const dfs = (temp,tempSum,index) =>{
        if(temp.length > k)//加一个长度的检验
            return;
        if(temp.length === k && tempSum === n){
            res.push([...temp]);
            return res;
        }
        for(let i = index; i <= 9; i++){
            if(tempSum + i <= n ){
                temp.push(i);
                dfs(temp, tempSum + i, i + 1);
                temp.pop();
            }
        }
        return;
    }

    dfs([], 0, 1);

    return res;
};

79 单词搜索

leetcode-cn.com/problems/wo…

/**
 * @param {character[][]} board
 * @param {string} word
 * @return {boolean}
 */
var exist = function(board, word) {
    let width = board[0].length - 1;
    let height = board.length - 1;

    const dfs = (i ,j , index) => {
        if(index === word.length)
            return true;
        
        if(i < 0 || i > height || j < 0 || j > width || board[i][j] !== word[index]){
            return false;
        }
    
        board[i][j] = '0';
        let flag = false;
        flag = dfs(i - 1, j, index + 1)||dfs(i + 1, j, index + 1)||dfs(i, j - 1, index + 1)||dfs(i, j + 1, index + 1);//有一个为true就返回,减少搜索时间

        board[i][j] = word[index];//回溯

        return flag;
    }

    for(let i = 0; i <= height; i++){
        for( let j = 0; j <= width; j++){
            if(board[i][j] === word[0]){
                if(dfs(i, j, 0)) 
                    return true;
            }
        }
    }
    return false;
};

46 全排列

leetcode-cn.com/problems/pe…

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permute = function(nums) {
    let res = [];//结果集
    /**
     * @param {number[]} temp 存放当前走的路径的值
     * @param set setNumes 记录当前路径上已经遍历过的索引 
     */
    const dfs=(temp,setNums)=>{
        //递归出口 当当前路径长度等于原数组长度的时候就可以加入res
        if(temp.length === nums.length){
            res.push(temp.slice(0));//返回一个新数组进行存放
            return;
        }
        
        for(let i = 0; i < nums.length; i++){
            if(!setNums.has(i)){//当前元素没有遍历过

                temp.push(nums[i]);//加入当前路径
                setNums.add(i);//加入set集

                dfs(temp, setNums);

                //回溯
                setNums.delete(i);
                temp.pop();
            }
        }
        return;

    }
    dfs([],new Set());
    return res;

};

47 全排列2

leetcode-cn.com/problems/pe…

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var permuteUnique = function(nums) {
    let res = [];
    nums.sort((a,b)=>(a - b));//排序
    
    const dfs = (temp,setNums) => {
        if(temp.length === nums.length){
            res.push([...temp]);//利用es6的解构也会返回新数组
            return;
        }
        for(let i = 0; i < nums.length; i++){
            if(!setNums.has(i)){
                //把同级的相同值的路径减枝掉
                if(i > 0 && !setNums.has(i-1) && nums[i] === nums[i-1]) continue;
                temp.push(nums[i]);
                setNums.add(i);
                dfs(temp,setNums);

                temp.pop();
                setNums.delete(i);
            }
        }
        return;
    }

    dfs([],new Set());

    return res;
};

332 重新安排行程(中)

leetcode-cn.com/problems/re…

/**
 * @param {string[][]} tickets
 * @return {string[]}
 */
var findItinerary = function(tickets) {
    tickets.sort((a,b)=>{
        if(a[0] === b[0])
            return a[1].localeCompare(b[1]);
        else
            return a[0].localeCompare(b[0]);
        
    });//localeCompares比价两个字符串的大小

    let res = [];
    let len = tickets.length;

    const dfs = (temp,num,setTic) => {
        if(num === len){
            res.push(temp);//最后一个目的地要push进去
            return true;
        }

        for(let i = 0; i < len; i++){
            if(tickets[i][0] === temp && !setTic.has(i)){//起点一致且没有使用过这个船票
                res.push(temp);
                setTic.add(i);
                let flag = dfs(tickets[i][1],num + 1,setTic);
                //如果没有找到就回溯
                if(!flag){
                    res.pop();
                    setTic.delete(i);
                }else{//如果找到就直接返回
                    return true;
                }
            }
        }
        return false;//所有票都遍历完也没找到 返回false
    }
    dfs('JFK',0, new Set());

    return res;

};

377 组合总和4(中)

leetcode-cn.com/problems/co…

/**
	回溯法会超时
 */
var combinationSum4 = function(nums, target) {
    let count = 0;

    const dfs = (tempSum) => {
        if(tempSum === target){
            count++;
            return;
        }

        for(let i = 0; i < nums.length; i++){
            if(tempSum + nums[i] <= target){
                dfs(tempSum + nums[i]);
            }
        }
        return;
    }
    dfs(0);
    return count;
};

37 解数独(难)

51 N皇后(难)