文章目录
- [1. 最长回文串(LC 409)](#1. 最长回文串(LC 409))
- [2. 增减字符串匹配(LC 942)](#2. 增减字符串匹配(LC 942))
- [3. 分发饼干(LC 455)](#3. 分发饼干(LC 455))
- [4. 最优除法(LC 553)](#4. 最优除法(LC 553))
- [5. 跳跃游戏II(LC 45)](#5. 跳跃游戏II(LC 45))
- [6. 跳跃游戏(LC 55)](#6. 跳跃游戏(LC 55))
1. 最长回文串(LC 409)
题目描述

解题思路
统计每个字符的个数,如果是偶数直接拼接,如果是奇数,取出偶数部分再拼接,如果最后剩余一个字符,再拼接到中间
代码实现
java
public int longestPalindrome(String s) {
int n = s.length();
int ret = 0;
int[] hash = new int[127];
for(int i=0;i<n;i++)
hash[s.charAt(i)-'A']++;
for(int a:hash)
ret+= a/2*2;
return ret<n?ret+1:ret;
}
2. 增减字符串匹配(LC 942)
题目描述

翻译:在字符串对应位置填入【0,n】,符合字符串的增或降的要求
解题思路
增的位置从小往大填,降的位置从大往小填
代码实现
java
public int[] diStringMatch(String s) {
int n = s.length();
char[] ss = s.toCharArray();
int[] ret = new int[n+1];
int ics = 0;
int d = n;
for(int i = 0;i<n;i++){
if(ss[i]=='I'){
ret[i] = ics;
ics++;
}else{
ret[i] = d;
d--;
}
}
ret[n] = ics;
return ret;
}
3. 分发饼干(LC 455)
题目描述

解题思路
类似优势洗牌
- 对两个数组进行排序
- 定义两个指针分别遍历两个数组,如果饼干能满足,计数器自增;否则就跳过,判断下一个饼干
代码实现
java
public int findContentChildren(int[] g, int[] s) {
int n1 = g.length;
int n2 = s.length;
Arrays.sort(g);
Arrays.sort(s);
int ret = 0;
int i=0, j = 0;
while(i<n1 && j<n2){
if(g[i]<=s[j]){
i++;
j++;
ret++;
}else
j++;
}
return ret;
}
4. 最优除法(LC 553)
题目描述

解题思路
- 经过一系列计算,这个表达式最终都可以写成
x/y的形式,只需要让x尽可能大,y
尽可能小 - nums[0]前没有符号,一定在分子部分;nums[1]前有除号,一定在分母部分,只需要给num[1]及后面数字一个括号,内部的除号就可以转化成乘号
代码实现
java
public String optimalDivision(int[] nums) {
int n = nums.length;
if(n==1)
return nums[0]+"";
if(n==2)
return nums[0]+"/"+nums[1];
StringBuilder ret = new StringBuilder();
ret.append(nums[0]+"/(");
for(int i = 1;i<n;i++)
ret.append(nums[i]+"/");
ret.deleteCharAt(ret.length()-1);
ret.append(")");
return ret.toString();
}
5. 跳跃游戏II(LC 45)
题目描述

解题思路
动态规划
- 状态表示:dp[i]表示到第i个位置最小跳跃次数
- 状态转移方程:dp[i]+arr[i]>=i 则 dp[i] = dp[j]+1,取最小值
- 初始化:dp[0] = 0,其余位置初始化为无穷大
贪心策略
类似层序遍历,找到每一次跳跃的左端点和右端点,如果哦前一次次的右端点大于当前的左端点,就直接覆盖,这里提现了贪心策略,尽可能减少跳跃次数

代码实现
- 动态规划
java
public int jump(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
Arrays.fill(dp,0x3f3f3f3f);
dp[0] = 0;
for(int i = 1;i<n;i++){
for(int j = 0;j<n;j++){
if(j+nums[j]>=i)
dp[i] = Math.min(dp[i],dp[j]+1);
}
}
return dp[n-1];
}
- 贪心策略
java
public int jump(int[] nums) {
int n = nums.length;
int ret = 0;
int left = 0;
int right = 0;
int maxpos = 0;
while(true){
if(maxpos>=n-1)
return ret;
for(int i = left;i<=right;i++)
maxpos = Math.max(maxpos,nums[i]+i);
ret++;
left = right+1;
right = maxpos;
}
}
6. 跳跃游戏(LC 55)
题目描述

解题思路
与上一题的思路相同,只需要判断最后left和right能否相遇
代码实现
java
public boolean canJump(int[] nums) {
int n = nums.length;
int left = 0;
int right = 0;
int maxpos = 0;
int ret = 0;
while(left<=right){
if(maxpos>=n-1)
return true;
for(int i= left;i<=right;i++)
maxpos = Math.max(maxpos,nums[i]+i);
left = right+1;
right = maxpos;
}
return false;
}