第二十七天
1405 最长快乐字符串
如果字符串中不含有任何 'aaa','bbb'
或'ccc'
这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。
给你三个整数 a
,b
,c
,请你返回 任意一个 满足下列全部条件的字符串 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[i−1][j]+dp[i][j−1]
初始状态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];
}
}