秋招打卡017(0828)


前言

提示:这里为每天自己的学习内容心情总结;

Learn By Doing,Now or Never,Writing is organized thinking.

现在就是巩固,每天看一点面经,刷题,打磨项目,积少成多。

需要持续的积累。

先多,后少。


提示:以下是本篇文章正文内容

一、今天学习了什么?

  • 刷题;

二、关于问题的答案

1、动态规划

	public int minDistance(String word1, String word2) {
        /**
         * dp[i][j],word1下标从(0,i-1)转换成word2下标从(0,j-1)的最少操作数
         */
        int m = word1.length();
        int n = word2.length();
        int[][] dp = new int[m + 1][n + 1];

        // base
        for (int i = 1; i <= m; i++) {
            dp[i][0] = i;
        }
        for (int j = 1; j <= n; j++) {
            dp[0][j] = j;
        }

        // dp过程
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
                    // 如果两个字符相同,那么就不需要操作
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    // 如果两个字符不同,有三种情况
                    // 1、替换
                    // 2、word2删除
                    // 3、word1删除
                    dp[i][j] = min(dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]) + 1;
                }
            }
        }

        return dp[m][n];
    }

    int min(int a, int b, int c) {
        a = a < b ? a : b;
        a = a < c ? a : c;
        return a;
    }
    public int countSubstrings(String s) {
        /**
         * dp[i][j],字符串s下标从(i,j)是否为回文字符串,true or false
         */
        boolean[][] dp = new boolean[s.length()][s.length()];

        int ans = 0;

        // dp 过程
        // 注意遍历顺序,从下到上,从左到右
        // 由于判断s[i,j]是否为回文字符串,和s[i+1,j-1]有关
        for (int i = s.length() - 1; i >= 0; i--) {
            for (int j = i; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    if (j - i <= 1) {
                        ans++;
                        dp[i][j] = true;
                    } else if (dp[i + 1][j - 1]) {
                        ans++;
                        dp[i][j] = true;
                    }
                }
            }
        }

        return ans;
    }
    public int longestPalindromeSubseq(String s) {
        /**
         * dp[i][j],代表s从下标(i,j)中最长的回文子序列
         */
        int[][] dp = new int[s.length()][s.length()];

        // base
        for (int i = 0; i < s.length(); i++) {
            dp[i][i] = 1;
        }

        // dp process
        for (int i = s.length() - 2; i >= 0; i--) {
            for (int j = i + 1; j < s.length(); j++) {
                if (s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = dp[i + 1][j - 1] + 2;
                } else {
                    // 如果不等的话,就是等于[i+1,j] or [i,j-1]的最大回文子序列长度
                    dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
                }
            }
        }

        return dp[0][s.length() - 1];
    }

2、贪心算法

    public int findContentChildren(int[] g, int[] s) {
        /**
         * - 我的思路是将胃口和饼干数量从小到大排序
         * - 排序完毕后,依次将胃口从小到大的人满足
         */
        Arrays.sort(g);
        Arrays.sort(s);

        int ans = 0;
        int index = 0;

        for (int i = 0; i < g.length; i++) {
            while (index < s.length && g[i] > s[index]) {
                index++;
            }
            if (index < s.length) {
                ans++;
            }
            index++;
            if (index >= s.length) {
                break;
            }
        }

        return ans;
    }
    public int wiggleMaxLength(int[] nums) {
        /**
         * prediff:记录之前的摆动
         * curdiff:现在的摆动
         */
        int ans = 1;// 摆动序列的最长子序列的长度,初始化为1
        int prediff = 0;
        int curdiff = 0;

        for (int i = 1; i < nums.length; i++) {
            curdiff = nums[i] - nums[i - 1];
            if ((prediff <= 0 && curdiff > 0) || (prediff >= 0 && curdiff < 0)) {
                ans++;
                prediff = curdiff;
            }
        }

        return ans;
    }
    public boolean canJump(int[] nums) {
        /**
         * cover : 能跳到的覆盖范围下标
         */
         int cover = nums[0];

        for (int i = 0; i <= cover; i++) {
            cover = Math.max(cover, i + nums[i]);
            if (cover >= nums.length - 1) {
                return true;
            }
        }
        return false;
    }
    public int jump(int[] nums) {
        /**
         * cur : 当前这一步能走到的最大下标范围
         * next : 下一步能跳跃的最大范围
         */
        int ans = 0;
        int cur = 0;
        int next = 0;

        for (int i = 0; i <= cur && cur < nums.length - 1; i++) {
            next = Math.max(next, i + nums[i]);
            if (i == cur) {
                ans++;
                cur = next;
            }
        }

        return ans;
    }
    public int largestSumAfterKNegations(int[] nums, int k) {
        /**
         * - 先将数组从小到大排序
         * - 反转数组前面的负数
         * - 判断k值
         */
        Arrays.sort(nums);

        for (int i = 0; i < nums.length; i++) {
            if (nums[i] < 0 && k > 0) {
                nums[i] = -nums[i];
                k--;
            }
        }

        if (k > 0 && k % 2 == 1) {
            Arrays.sort(nums);
            nums[0] = -nums[0];
        }

        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            res += nums[i];
        }

        return res;
    }

总结

提示:这里对文章进行总结:

今天结束了动态规划篇的刷题,进入了贪心算法。

贪心算法指的是每一步都是最优解,然后达到最后结果的全局最优解。也需要将一个问题拆分成为小问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值