LeetCode刷题日记(Day10)

Problem 56. Merge Intervals

  • 题目描述
    Given a collection of intervals, merge all overlapping intervals.

    Example:

    Input: [[1,3],[2,6],[8,10],[15,18]]
    Output: [[1,6],[8,10],[15,18]]
    Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
    
  • 解题思路
    首先,对 intervals 中所有的元素进行排序,这里使用了 algorithm 头文件里面的 sort 函数,需要自己写一个 cmp 比较函数。
    对升序排列的区间,进行如下操作:

  1. 初始化 left = intervals[0].start,right = intervals[0].end,定义变量 res 用于返回结果
  2. 从 intervals[1] 开始对 intervals 进行遍历。如果 intervals[i].start <= right,则说明可能要进行区间合并,此时将 right 和 intervals[i].end 中的最大值赋值给 right;如果 intervals[i].start > right,说明无需进行区间合并,只需要将前一个区间保存在 res 中,并更新 left 和 right 为intervals[i].start 和 intervals[i].end
  3. 在遍历完毕后,将最后一个区间存入 res 中
  • 代码实现
class Solution {
public:
    vector<Interval> merge(vector<Interval>& intervals) {
        vector<Interval> res;
        int len = intervals.size();
        if (len == 0)
            return res;
        sort(intervals.begin(), intervals.end(), cmp);
        int left = intervals[0].start, right = intervals[0].end;
        for(int i = 1; i < len; ++i){
            if(intervals[i].start <= right)
                right = max(right, intervals[i].end);
            else{
                res.push_back(Interval(left, right));
                left = intervals[i].start;
                right = intervals[i].end;
            }
        }
        res.push_back(Interval(left, right));
        return res;
    }
    static bool cmp(const Interval &a, const Interval &b){
        if (a.start < b.start) 
            return true;
        return false;
    }
};

Problem 62. Unique Paths

  • 题目描述
    A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).

    The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).

    How many possible unique paths are there?

  • 解题思路
    令 path[i][j] 表示从起点到点 (i, j) 的不同路径数,由题可知,若要到达点 (i, j),只能从点 (i-1, j)向下走或者从点 (i, j-1) 向右走,即到达点 (i, j) 的不同路径数 = 到达点 (i-1, j) 的路径数 + 到达点 (i, j-1) 的路径数。

    写出递推式:
    path[i][j] = path[i-1][j] + path[i][j-1]

    其中边界条件为:
    path[0][0] = path[0][j] = path[i][0] = 1

  • 代码实现

class Solution {
public:
    int uniquePaths(int m, int n) {
        int path[100][100];
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                if(i == 0 || j == 0) 
                    path[i][j] = 1;
                else
                    path[i][j] = path[i-1][j] + path[i][j-1];
            }
        }
        return path[m-1][n-1];
    }
};

Problem 66. Plus One

  • 题目描述
    Given a non-empty array of digits representing a non-negative integer, plus one to the integer.

    The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.

    You may assume the integer does not contain any leading zero, except the number 0 itself.

    Example:

    Input: [1,2,3]
    Output: [1,2,4]
    Explanation: The array represents the integer 123.
    
  • 解题思路
    定义变量 carry 表示进位,并初始化为1。对输入的 digits 进行倒序遍历,并做加法运算,有进位则将 carry 更新为1,否则更新为0;
    若首元素有进位,则利用 insert 函数将1插入到 digits 首位。

  • 代码实现

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int carry = 1;
        for(int i = digits.size()-1; i >= 0; --i){
            int temp = digits[i] + carry;
            carry = temp / 10;
            digits[i] = temp % 10;
        }
        if(carry == 1)
            digits.insert(digits.begin(), 1);
        return digits;
    }
};

Problem 69. Sqrt(x)

  • 题目描述
    mplement int sqrt(int x).

    Compute and return the square root of x, where x is guaranteed to be a non-negative integer.

    Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

  • 解题思路
    利用二分查找求平方根。

  • 代码实现

class Solution {
public:
    int mySqrt(int x){
        if (x <= 1)
            return x;
        int left = 1, right = x, mid, sqrt;
        while(left <= right){
            mid = left + (right-left)/2;
            sqrt = x/mid;
            if (sqrt == mid)
                return mid;
            if (sqrt < mid)
                right = mid - 1;
            else 
                left = mid + 1;
        }
        return right;
    }
};

Problem 70. Climbing Stairs

  • 题目描述
    You are climbing a stair case. It takes n steps to reach to the top.

    Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

    Note: Given n will be a positive integer.

    Example:

    Input: 3
    Output: 3
    Explanation: There are three ways to climb to the top.
    1. 1 step + 1 step + 1 step
    2. 1 step + 2 steps
    3. 2 steps + 1 step
    
  • 解题思路
    这是爬楼梯问题,一次只能爬1阶或者2阶楼梯,问一个n阶楼梯共有多少种爬法,解题思路如下:
    令f(n)为到达第n阶楼梯的走法。要想到达第n阶楼梯,则必须要先到达第n-1阶楼梯,或者第n-2阶楼梯,所以有f(n) = f(n-1) + f(n-2),其中f(1) = 1,f(2) = 2。
    递推表达式得到之后,有以下四种办法求解:

  1. 递归的办法,即直接返回 climbStairs(n-1) + climbStairs(n-2),但当n比较大时会出现超时问题,不建议采纳。
  2. 动态规划的办法,创建一个dp数组,不断进行赋值,最后返回dp[n]即可,这种方法可采纳,只不过效率低下,且需要比较高的空间开销。
  3. 非递归的解法,效率高,空间消耗小,代码已给出。
  4. 直接求出f(n)的函数表达式,效率最高,时间复杂度和空间复杂度都是O(1),但需要一定的数学能力。
  • 代码实现
class Solution {
public:
    int climbStairs(int n) {
        if(n == 1)
            return 1;
        if(n == 2)
            return 2;
        long long f1 = 1, f2 = 2, f3;
        for(int i = 3; i <= n; ++i){
            f3 = f1 + f2;
            f1 = f2;
            f2 = f3;
        }
        return f3;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_36348299/article/details/88583421