最大数
给定任意一个数字 n,然后给出数字 m,则需在 n 中去掉 m 位数,保持各位顺序不变的情况下,得到最大数。
解决思路
- 从
[0,n-m-1]
里面获取最大元素。然后每个元素都要在最大元素后面获取元素。
Java实现
public class MaxNum {
public static void main(String[] args) {
int num = 12967;
int m = 3;
String str = String.valueOf(num);
char[] chars = str.toCharArray();
int k = 0;
int n = chars.length;
char[] res = new char[n - m];
for (int i = 0; i < n - m; i++) {
for (int j = k; j < i + m + 1; j++) {
if (res[i] < chars[j]) {
res[i] = chars[j];
k = j + 1;
}
}
}
System.out.println(new String(res));
}
}
409. 最长回文串
给定一个包含大写字母和小写字母的字符串 s
,返回 通过这些字母构造成的 最长的回文串 。
在构造过程中,请注意 区分大小写 。比如 "Aa"
不能当做一个回文字符串。
输入:s = "abccccdd"
输出:7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
解决思路
- 对每个字符进行计数,偶数直接添加到总长度中,奇数是
(count[i] / 2) * 2
。如果有多余的数,添加到中间。
Java实现
class Solution {
public int longestPalindrome(String s) {
int[] count = new int[128];
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
count[c]++;
}
int ans = 0;
for (int i = 0; i < 128; i++) {
ans += (count[i] / 2) * 2;
}
return Math.min(ans + 1, s.length());
}
}
5. 最长回文子串
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
解题思路
-
l
是字符串的左边,r
是字符串的右边。 - 因为递推公式是如果左边字符和右边字符相等,则
dp[l][r]= dp[l + 1][r - 1]
。所以优先计算右边比较小的。 - 如果要计算回文字符串的数量,右边是可以到0的,左边是可以到右边的。
Java实现
class Solution {
public String longestPalindrome(String s) {
int n = s.length();
int maxRight = 0;
int maxLeft = 0;
int len = 1;
boolean[][] dp = new boolean[n][n];
for (int r = 0; r < n; r++) {
for (int l = 0; l <= r; l++) {
if (s.charAt(l) == s.charAt(r) && ((r - l <= 2) || dp[l + 1][r - 1])) {
dp[l][r] = true;
if (r - l + 1 > len) {
len = r - l + 1;
maxLeft = l;
maxRight = r;
}
}
}
}
return s.substring(maxLeft, maxRight + 1);
}
}
647. 回文子串
输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
解决思路
同上
516. 最长回文子序列
给你一个字符串 s
,找出其中最长的回文子序列,并返回该序列的长度。
子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
解决思路
- 计算结果得出是根据左边和下边。所有优先计算下面的元素和左边的元素。i最大是下面,j最小是左边。
Java实现
class Solution {
public int longestPalindromeSubseq(String s) {
int[][] dp = new int[s.length()][s.length()];
int n = s.length();
for (int i = n - 1; i >= 0; i--) {
dp[i][i] = 1;
//(0,3) 的数据是由(1,3)和(0,2)得到的。即下面和左边得到的最大值。
for (int j = i + 1; j < n; j++) {
//最先计算的数是(2,3),由(2,2)和(3,3)推出来。左边和下边。所有优先计算下面的元素和左边的元素。i最大是下面,j最小是左边。
System.out.println(i + "," + j);
if (s.charAt(i) != s.charAt(j)) {
dp[i][j] = Math.max(dp[i + 1][j], dp[i][j - 1]);
} else {
dp[i][j] = dp[i + 1][j - 1] + 2;
}
}
}
return dp[0][n - 1];
}
在这里插入图片描述