代码改变世界

LeetCode算法编程之连载一

2014-11-02 23:59  commandow  阅读(1191)  评论(4编辑  收藏  举报

今天看到酷壳推荐的国外编程LeetCode算法编程网站,上面目前有154道算法题,感觉很有意思,平常工作也比较忙,现在很少有时间来锻炼算法相关的东西,有空的时候静下心来,温习下基础,活跃下自已的思路,也是有必要的。先做了几道,后面会陆续补充其它的题目。

1、题目-PlusOne

Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such that the most significant digit is at the head of the list.

首先解释下题目,这道题的意思是:

用一个数组来代表一个非负整数,对这个整数进行+1操作,得到的结果也用数组进行表示。这个题目有假设前提:数组里的数字都是在0-9范围内的(刚开始弄迷惑了,以为数组里的数字可以是任意大的值,这样来解这道题的话,会非常困难)


分析

知道前提后,这个题目就比较简单了,从数组最后一位开始,每个位需要判断是否需要进位,如果进位,自已设为0,否则自增即可。直接附源码

class Solution {
public:
    vector<int> plusOne(vector<int> &digits) {
int size = digits.size(); if (digits[size - 1] < 9) { digits[size - 1] += 1; return digits; } // 是否需要进位 bool carry = true; for (int i = size - 1; i >= 0; i --) { if (!carry) { break; } if (digits[i] == 9) { carry = true; // 进位后,原位置0 digits[i] = 0; if (i == 0) { // 数组首个数字进位后,需要新插入数字首位 digits.insert(digits.begin(), 1); } } else { // 不进位,就退出了 carry = false; digits[i] += 1; } } return digits; } };

2、题目二 - Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

题目解释:

给出一个 m x n 的矩阵由非负整数组成,找到一条路线(从左上角到右下解)使得路线中经过的数字的累加和最小。

注意:行进的路线只能向下或向右


分析

很明显这道题,是需要找最优解的题目,而找最优解的问题,最适合的就是动态规划。

一个动态规划算法的几个关键点:
1)怎么描述问题,要把问题描述为交叠的子问题
2)交叠子问题的初始条件(边界条件)
3)动态规划在形式上往往表现为填矩阵的形式
4)填矩阵的方式(或者说顺序)表明了什么?--它表明了这个动态规划从小到大产生的过程,专业点的说就是递推式的依赖形式决定了填矩阵的顺序

大家可以思考下后,再参考源码:

/*****************************************************************
采用动态规划的思想:
1)最优解公式
C(i, j) = Min[ C(i-1, j), C(i, j - 1) ] + Grid[i][j], i > 0, j > 0
2)初始值的边界情况:
当 i == 0, j == 0时,C(i, j) = Grid[i][j]
当 i == 0, j > 0时,C(i, j) = C(i, j - 1) + Grid[i][j]
当 i > 0, j == 0时,C(i, j) = C(i -1, j) + Grid[i][j]
******************************************************************/

class Solution {
public:
    int minPathSum(vector<vector<int> > &grid) {

        int m = grid.size();
        int n = grid[0].size();

        // 最优解矩阵
        vector<vector<int> > c;

        vector<int> e;
        int d = 0;
        
        for (int i = 0; i < m; i ++)
        {
            e.clear();

            for (int j = 0; j < n; j ++)
            {
                
                if (i == 0)
                {
                    d += grid[i][j];
                    e.push_back(d);

                    continue;
                }

                if (j == 0)
                {
                    d = c[i - 1][j] + grid[i][j];
                    e.push_back(d);
                    continue;
                }

                d = d > c[i - 1][j] ? c[i - 1][j] + grid[i][j] : d + grid[i][j];
                e.push_back(d);
            }

            // 一行一行的计算最优解
            c.push_back(e);
        }

        return c[m - 1][n - 1];
    }
};