public String longestPalindrome(String s) {
String res = "";
for (int i = 0; i < s.length(); i++) {
// 以 s[i] 为中心的最长回文子串
String s1 = palindrome(s, i, i);
// 以 s[i] 和 s[i+1] 为中心的最长回文子串
String s2 = palindrome(s, i, i + 1);
// res = longest(res, s1, s2)
res = res.length() > s1.length() ? res : s1;
res = res.length() > s2.length() ? res : s2;
}
return res;
}
String palindrome(String s, int l, int r) {
// 防止索引越界
while (l >= 0 && r < s.length()
&& s.charAt(l) == s.charAt(r)) {
// 向两边展开
l--;
r++;
}
// 返回以 s[l] 和 s[r] 为中心的最长回文串
return s.substring(l + 1, r);
}
public List<String> result = new LinkedList<>();
public List<String> generateParenthesis(int n) {
StringBuffer sb = new StringBuffer();
blackTrack(n,n,result,sb);
return result;
}
private void blackTrack(int left, int right, List<String> result, StringBuffer sb) {
if (left > right){
return;
}
if (left < 0 || right < 0){
return;
}
if (left == 0 && right == 0){
result.add(sb.toString());
}
sb.append("(");
blackTrack(left-1,right,result,sb);
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
blackTrack(left,right-1,result,sb);
sb.deleteCharAt(sb.length()-1);
}
public int longestValidParentheses(String s) {
Stack<Integer> stack = new Stack<>();
int[] dp = new int[s.length()+1];
for (int i = 0; i < s.length(); i++){
if (s.charAt(i) == '('){
stack.push(i);
dp[i+1] = 0;
}else {
if (!stack.isEmpty()){
int leftIndex = stack.pop();
int len = 1 + i - leftIndex + dp[leftIndex];
dp[i+1] = len;
}else {
dp[i+1] = 0;
}
}
}
int res = 0;
for (int i = 0; i < dp.length; i++){
res = Math.max(res,dp[i]);
}
return res;
}
public int trap(int[] height) {
if (height.length == 0) {
return 0;
}
int n = height.length;
int res = 0;
// 数组充当备忘录
int[] l_max = new int[n];
int[] r_max = new int[n];
// 初始化 base case
l_max[0] = height[0];
r_max[n - 1] = height[n - 1];
// 从左向右计算 l_max
for (int i = 1; i < n; i++)
l_max[i] = Math.max(height[i], l_max[i - 1]);
// 从右向左计算 r_max
for (int i = n - 2; i >= 0; i--)
r_max[i] = Math.max(height[i], r_max[i + 1]);
// 计算答案
for (int i = 1; i < n - 1; i++)
res += Math.min(l_max[i], r_max[i]) - height[i];
return res;
}
public int jump(int[] nums) {
int n = nums.length;
int end = 0, farthest = 0;
int jumps = 0;
for (int i = 0; i < n - 1; i++) {
farthest = Math.max(nums[i] + i, farthest);
if (end == i) {
jumps++;
end = farthest;
}
}
return jumps;
}
public int maxSubArray(int[] nums) {
int n = nums.length;
if (n == 0) return 0;
int[] dp = new int[n];
// base case
// 第一个元素前面没有子数组
dp[0] = nums[0];
// 状态转移方程
for (int i = 1; i < n; i++) {
dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
}
// 得到 nums 的最大子数组
int res = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
public boolean canJump(int[] nums) {
int n = nums.length;
int farthest = 0;
for (int i = 0; i < n - 1; i++) {
// 不断计算能跳到的最远距离
farthest = Math.max(farthest, i + nums[i]);
// 可能碰到了 0,卡住跳不动了
if (farthest <= i) {
return false;
}
}
return farthest >= n - 1;
}
public int uniquePaths(int m, int n) {
return dp(m - 1, n - 1);
}
// 定义:从 (0, 0) 到 (x, y) 有 dp(x, y) 条路径
int dp(int x, int y) {
if (x == 0 && y == 0) {
return 1;
}
if (x < 0 || y < 0) {
return 0;
}
// 状态转移方程:
// 到达 (x, y) 的路径数等于到达 (x - 1, y) 和 (x, y - 1) 路径数之和
return dp(x - 1, y) + dp(x, y - 1);
}
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
// 数组索引偏移一位,dp[0][..] dp[..][0] 代表 obstacleGrid 之外
// 定义:到达 obstacleGrid[i][j] 的路径条数为 dp[i-1][j-1]
int[][] dp = new int[m + 1][n + 1];
// base case:如果没有障碍物,起点到起点的路径条数就是 1
dp[1][1] = obstacleGrid[0][0] == 1 ? 0 : 1;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1) {
// 跳过 base case
continue;
}
if (obstacleGrid[i - 1][j - 1] == 1) {
// 跳过障碍物的格子
continue;
}
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
// 返回到达 obstacleGrid[m-1][n-1] 的路径数量
return dp[m][n];
}
</