1.不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
(1)思路:想要到达一个坐标如(i, j),只能从(i-1, j)和(i, j-1)经过1Down or 1Right完成;因此,将原问题分解为分别经过坐标(i-1, j)和(i, j-1)的两个独立子问题,因此搜索空间从[(0, 0),(i, j)]化归为[(0, 0), (i-1, j)] 和[(0, 0), (i, j-1)]。很明显可以看出这两个搜索空间高度重合,因此使用自底向上的迭代法依次求解。
(2)代码:
class Solution {
public int uniquePaths(int m, int n) {
int[] dp = new int[n];
for(int j = 0;j < n;j++) dp[j] = 1;
for(int i = 1;i < m;i++) {
for(int j = 1;j < n;j++) {
dp[j] = dp[j] + dp[j-1];
}
}
return dp[n-1];
}
}
2.最大子数组和
给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。
(1)思路:定义一个函数f(n),以第n个数为结束点的子数列的最大和,存在一个递推关系f(n) = max(f(n-1) + A[n], A[n]);将这些最大和保存下来后,取最大的那个就是,最大子数组和。因为最大连续子数组 等价于 最大的以n个数为结束点的子数列和附代码。
(2)代码:
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if(nums.size() == 0) return NULL;
int res = INT_MIN;
int f_n = -1;
for(int i = 0; i < nums.size(); ++i){
f_n = max(nums[i], f_n + nums[i]);
res = max(f_n, res);
}
return res;
}
};
3.合并区间
(1)思路:第一次遍历intervals数组。设计一个数组int[] exist 来保存开头和结尾。开头写2,身体和结尾写1。第二遍遍历exist数组。根据数组内的信息确定覆盖后的区间。
(2)代码:
class Solution {
public int[][] merge(int[][] intervals) {
int left = intervals[0][0], right = intervals[0][1];
int[] exist = new int[10002];
for (int i = 0; i < intervals.length; i++) {
left = Math.min(left,intervals[i][0]);
right = Math.max(right,intervals[i][1]);
if (exist[intervals[i][0]] == 0)exist[intervals[i][0]] = 2;
for (int j = intervals[i][0]+1; j <= intervals[i][1] ; j++) {
exist[j] = 1;
}
}
List<int[]> vector = new ArrayList<>();
int l = left,r;
for (int i = left; i <= right ; i++) {
System.out.print(exist[i]+" ");
if (exist[i]!=0&&exist[i+1]!=1)vector.add(new int[]{l,i});
if (exist[i+1]==2)l = i+1;
}
int[][] a = new int[vector.size()][2];
return vector.toArray(a);
}
}
4.旋转图像
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
(1)思路:以四个顶点为关注点, 一个点的坐标是matrix[x][y],顺时针旋转就是:左上角y+1、右上角x+1,右下角y-1,左下角x-1。从外圈一圈一圈往里遍历交换。
(2)代码:
class Solution {
public static void rotate(int[][] matrix) {
int n = matrix.length - 1;
for (int i = 0; i <= matrix.length / 2; i++) {
for (int j = i; j < n - i; j++) {
int a = matrix[i][j];
int b = matrix[j][n-i];
int c = matrix[n-i][n-j];
int d = matrix[n-j][i];
matrix[i][j] = d;
matrix[j][n-i] = a;
matrix[n-i][n-j] = b;
matrix[n-j][i] = c;
}
}
}
}
5.买卖股票的最佳时机Ⅱ
给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。
在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
(1)思路:当第二天的价格高于第一天的时候就增加第二天减去第一天的,否则就加0。
(2)代码:
class Solution {
public int maxProfit(int[] prices) {
int max = 0;
for(int i = 1; i < prices.length; i++){
int rate = prices[i] - prices[i - 1];
max = max + (rate > 0 ? rate : 0);
}
return max;
}
}