美文网首页
回溯,贪心,动态规划

回溯,贪心,动态规划

作者: 知止9528 | 来源:发表于2021-02-22 00:00 被阅读0次

1.回溯算法思想
leetcode 112 号算法题:路径总和
leetcode 113 号算法题:路径总和 II
leetcode 46 号算法题:全排列
leetcode 47 号算法题:全排列 II
leetcode 77 号算法题:组合

leetcode 39 号算法题:组合总和

// 输入:candidates = [2,3,6,7], target = 7,
//所求解集为:
//[
// [7],
// [2,2,3]
//]

public List<List<Integer>> combinationSum(int[] candidates, int target) {
            int len = candidates.length;
            List<List<Integer>> res = new ArrayList<>();
            if (len == 0) {
                return res;
            }

            Deque<Integer> path = new ArrayDeque<>();
            dfs(candidates, 0, len, target, path, res);
            return res;
        }

        /**
         * @param candidates 候选数组
         * @param begin      搜索起点
         * @param len        冗余变量,是 candidates 里的属性,可以不传
         * @param target     每减去一个元素,目标值变小
         * @param path       从根结点到叶子结点的路径,是一个栈
         * @param res        结果集列表
         */
        private void dfs(int[] candidates, int begin, int len, int target, Deque<Integer> path, List<List<Integer>> res) {
            // target 为负数和 0 的时候不再产生新的孩子结点
            if (target < 0) {
                return;
            }
            if (target == 0) {
                res.add(new ArrayList<>(path));
                return;
            }

            // 重点理解这里从 begin 开始搜索的语意
            for (int i = begin; i < len; i++) {
                path.addLast(candidates[i]);

                // 注意:由于每一个元素可以重复使用,下一轮搜索的起点依然是 i,这里非常容易弄错
                dfs(candidates, i, len, target - candidates[i], path, res);

                // 状态重置
                path.removeLast();
            }
        }

leetcode 40 号算法题:组合总和 Ⅱ

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            int len = candidates.length;
            List<List<Integer>> res = new ArrayList<>();
            if (len == 0) {
                return res;
            }

            Deque<Integer> path = new ArrayDeque<>();
            Arrays.sort(candidates);
            dfs(candidates, 0, len, target, path, res);
            return res;
        }

        /**
         * @param candidates 候选数组
         * @param begin      搜索起点
         * @param len        冗余变量,是 candidates 里的属性,可以不传
         * @param target     每减去一个元素,目标值变小
         * @param path       从根结点到叶子结点的路径,是一个栈
         * @param res        结果集列表
         */
        private void dfs(int[] candidates, int begin, int len, int target, Deque<Integer> path, List<List<Integer>> res) {
            if (target == 0) {
                res.add(new ArrayList<>(path));
                return;
            }

            // 重点理解这里从 begin 开始搜索的语意
            for (int i = begin; i < len; i++) {
                // 大剪枝:减去 candidates[i] 小于 0,减去后面的 candidates[i + 1]、candidates[i + 2] 肯定也小于 0,因此用 break
                if(target-candidates[i]<0){
                    break;
                }

                // 小剪枝:同一层相同数值的结点,从第 2 个开始,候选数更少,结果一定发生重复,因此跳过,用 continue
                if(i>begin && candidates[i]==candidates[i-1]){
                    System.out.println("i>>"+i+">>begin>>"+begin);
                    continue;
                }

                path.addLast(candidates[i]);
                System.out.println("递归之前 => " + path + ",剩余 = " + (target - candidates[i]));

                //因为不能重复  所以是i+1
                dfs(candidates, i+1, len, target - candidates[i], path, res);

                path.removeLast();
                System.out.println("递归之后 => " + path);
            }
        }

leetcode 216 号算法题:组合总和 Ⅲ

public List<List<Integer>> combinationSum3(int k, int n) {
            Deque<Integer> list = new LinkedList<>();
            List<List<Integer>> re = new ArrayList<>();
            dfs(1, re, k, n, list);

            return re;
        }

        private void dfs(int begin, List<List<Integer>> result, int count, int target, Deque<Integer> list) {
            if (count == 0 && target == 0) {
                result.add(new ArrayList<>(list));
                return;
            }


            for (int i = begin; i <=9; i++) {
                if (count < 0 || target < 0) {
                    break;
                }
                System.out.println("beigin的值>>"+begin);
                list.addLast(i);

                System.out.println("递归之前 => " + list + ",剩余 = " + (target - i));
                //因为不能重复  所以从i+1开始
                dfs(i + 1, result, count - 1, target - i, list);
                list.removeLast();
                System.out.println("递归之后 => " + list);
            }

        }

leetcode 78 号算法题:子集
leetcode 90 号算法题:子集Ⅱ
leetcode 17 号算法题:电话号码的字母组合
leetcode 93 号算法题:复原 IP 地址
leetcode 22 号算法题:括号生成
leetcode 51 号算法题:N 皇后
leetcode 37 号算法题:数独问题


2.贪心算法思想
leetcode 455 号算法题:分发饼干
leetcode 322 号算法题:零钱兑换
leetcode 45 号算法题:跳跃游戏 Ⅱ
leetcode 1578 号算法题:避免重复字母的最小删除成本
leetcode 402 号算法题:移掉K位数字


3.动态规划算法思想
leetcode 509 号算法题:斐波那契数
leetcode 322 号算法题:零钱兑换
leetcode 64 号算法题:最小路径和
leetcode 53 号算法题:最大子数组之和


最大连续子序列和

public static int maxSubArray(int [] nums){

        int [] dp=new int[nums.length];
        int  max=dp[0];

        for (int i = 1; i < nums.length; i++) {

            if(dp[i-1]<0){
                dp[i]=nums[i];
            }else {
                dp[i]=nums[i]+dp[i-1];
            }
            max=Math.max(max,dp[i]);
        }
        return max;
    }

leetcode 647 号算法题:回文子串
leetcode 5 号算法题:最长回文串

public String longestPalindrome(String s) {
        if(s==null){
            return null;
        }
        char[] chars = s.toCharArray();
        if(chars.length==0){
            return s;
        }
        //可能情况
        //一  i-dp[i-1]-1位置和 i位置相同  则dp[i]=dp[i-1]+2
        //二  不相同  则dp[i]=1
        boolean [][] dp=new boolean[chars.length][chars.length];
        int maxLen=1;
        int begin=0;
        for(int i=chars.length-1;i>=0;i--){

            for(int j=i;j<chars.length;j++){
                int len=j-i+1;
                dp[i][j]=chars[i]==chars[j]&&(len<=2 || dp[i+1][j-1]);
                if(dp[i][j]&&len>maxLen){
                    maxLen=len;
                    begin=i;
                }
            }
        }
        return new String(chars,begin,maxLen);
    }

leetcode 131 号算法题:分割回文串
leetcode 516 号算法题:最长回文子序列


leetcode 300 号算法题:最长上升子序列
//输入:nums = [10,9,2,5,3,7,101,18]
//输出:4
//解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。

public int lengthOfLIS(int[] nums) {
        if(nums==null || nums.length==0) return 0;
        int [] dp=new int[nums.length];
        int max=dp[0]=1;
        for (int i = 1; i < nums.length; i++) {
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(nums[j]>=nums[i]){
                    continue;
                }else{
                    dp[i]=Math.max(dp[i],dp[j]+1);
                }
            }
            max=Math.max(max,dp[i]);
        }
        return max;
    }

leetcode 1143 号算法题:最长公共子序列
leetcode 72 号算法题:编辑距离
leetcode 44 号算法题:通配符匹配
leetcode 10 号算法题:正则表达式匹配
leetcode 486 号算法题:预测赢家
leetcode 877 号算法题:石子游戏
最长有效括号
0-1 背包问题

相关文章

  • 回溯,贪心,动态规划

    1.回溯算法思想leetcode 112 号算法题:路径总和leetcode 113 号算法题:路径总和 IIle...

  • 动态规划

    问题 什么样的问题可以用动态规划解决?解决动态规划问题的一般思考过程是什么样的?贪心、分治、回溯、动态规划这四种算...

  • 一、基础算法分析类型

    常见的算法分析类型如下: 1、分治法 2、动态规划法 3、回溯法 4、分支限界法 5、贪心法

  • 常用几种算法

    贪心,分治,回溯,动态规划四种算法。 贪心算法 场景:我们有m个糖果和n个孩子,现在要把糖果分给这些孩子吃,但是糖...

  • 动态规划理论与案例

    一、为什么要使用动态规划 在前面的文章中,我们介绍了贪心算法、回溯算法,它们和动态规划一样,通常都可以用来解决多阶...

  • 贪心、回溯、动态规划的形象比喻

    贪心:一条路走到黑,就一次机会,只能哪边看着顺眼走哪边 回溯:一条路走到黑,无数次重来的机会,还怕我走不出来 (S...

  • 算法篇 - 递归,回溯,动态规划, 贪心

    递归就是自我调用,经常作为一种编程的实现方式,比如题主问题中的DFS 、动态规划、回溯法都可以用递归来实现,当然也...

  • 动态规划

    --tags: 算法,动态规划 动态规划解题 引入:动态规划 和贪心法 都是算法的思想方法 贪心算法——像 第一类...

  • 数据结构与算法简述(下)

    目录: 算法简介 排序算法 递归与穷举 贪心与分治 动态规划和回溯 1.算法简介 解题方案的准确而完整的描述,是一...

  • 互联网大厂常考算法及套路深度解析

    常考算法 暴力法 回溯法 分支限界法 分治法 动态规划 贪心法 暴力法 也称枚举法、穷举法、蛮力法。 基本思想: ...

网友评论

      本文标题:回溯,贪心,动态规划

      本文链接:https://www.haomeiwen.com/subject/zoccfltx.html