leetcode刷题第27天——1405,45,62

本文介绍了一篇关于利用贪心策略解决编程问题的文章,涉及三个主题:寻找满足特定条件的最长快乐字符串(字符限制),最少跳跃次数到达数组尾部,以及计算从起点到终点的不同路径。通过实例展示了如何运用贪心算法优化解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第二十七天

1405 最长快乐字符串

如果字符串中不含有任何 'aaa','bbb''ccc'这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。

给你三个整数 abc,请你返回 任意一个 满足下列全部条件的字符串 s

  • s 是一个尽可能长的快乐字符串。
  • s最多a 个字母'a'b 个字母'b'c 个字母 'c'
  • s 中只含有 'a''b''c' 三种字母。
  • 如果不存在这样的字符串 s ,请返回一个空字符串 ""
方法 贪心

每次都选择剩余数量最多的字符作为下一个要填充的字符,如果出现连续两个字符相同,那么就选择第二多的字符,否则选择第三多的字符。

oops:这题是真难受,代码写的贼长,太不优雅了。

class Solution {
    public static StringBuilder stringBuilder;
    public String longestDiverseString(int a, int b, int c) {
        stringBuilder = new StringBuilder("");
        int[] count = new int[]{2, 2, 2};
        while (true){
            int chr = choose(new int[]{a * flag(count[0]), b * flag(count[1]), c * flag(count[2])});
            if (chr == -1) break;
            if (chr == 0) {
                stringBuilder.append('a');
                a--;
                change(count, 0);
            }
            else if (chr == 1){
                stringBuilder.append('b');
                b--;
                change(count, 1);
            }
            else{
                stringBuilder.append('c');
                c--;
                change(count, 2);
            }
        }
        return stringBuilder.toString();
    }

    public static int choose(int[] vars){
        int res = 0, index = -1;
        for (int i = 0; i < 3; ++i) if (vars[i] > res) {index = i; res = vars[i];};
        return index;
    }
    public int flag(int x){return x > 0 ? 1 : 0;}
    public static void change(int[] count, int i){count[i]--; count[(i + 1) % 3 ] = 2; count[(i + 2) % 3] = 2;}

}

45 跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

假设你总是可以到达数组的最后一个位置。

方法 贪心

用一个队列记录每一次到 上次能够到达的最大位置 时,数组中出现的最大位置,当到达 上一次能够到达的最大位置 时,更新步数,这样就保证了 在上一个能够到达的最大位置之前,每一个位置的步数都是最少的。遍历整个数组,直到整个数组的尾部,然后返回steps即可。steps记录的是:在第i次循环中,到达位置i的最少步数。

class Solution {
    public int jump(int[] nums) {
        if (nums.length == 1) return 0;
        int steps = 0, index = 0, maxJump = nums[0];
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(maxJump);
        boolean firstStep = true;
        while (index < nums.length){
            int max = queue.peek();
            if (nums[index] + index > maxJump){
                maxJump = nums[index] + index;
            }//一直更新maxJump 记录所经过的路径上能够到达的最大位置
            if (index <= max) { //在没有到达上一次的最大位置时 只有第一次会让steps+1,因为在原地steps为0
                if (firstStep) {
                    steps++;
                    firstStep = false;
                }
            }
            if (index == max){ //当前位置到达了上一次能够到达的最大位置 此时需要更新max 同时让下一次循环 steps+1
                queue.poll();
                firstStep = true;
                queue.offer(maxJump);
            }
            index++;
        }
        return steps;
    }
}

62 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start”)。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径?

方法

考虑从倒数第二格到最后一格的方法数,一共有两种方法,假设最后一个是(i,j)

  • (i-1,j)(i,j)
  • (i,j-1)(i,j)

因此,可以得到状态转移方程如下:
dp[i][j]=dp[i−1][j]+dp[i][j−1] dp[i][j]=dp[i-1][j]+dp[i][j-1] dp[i][j]=dp[i1][j]+dp[i][j1]
初始状态dp[0->m][0]=1,dp[0][0->n]=1

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for (int i = 0; i < m; ++i) dp[i][0] = 1;
        for (int j = 0; j < n; ++j) dp[0][j] = 1;
        for (int i = 1; i < m; ++i){
            for (int j = 1; j < n; ++j){
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值