算法练习题

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;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值