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 比较函数。
对升序排列的区间,进行如下操作:
- 初始化 left = intervals[0].start,right = intervals[0].end,定义变量 res 用于返回结果
- 从 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
- 在遍历完毕后,将最后一个区间存入 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。
递推表达式得到之后,有以下四种办法求解:
- 递归的办法,即直接返回 climbStairs(n-1) + climbStairs(n-2),但当n比较大时会出现超时问题,不建议采纳。
- 动态规划的办法,创建一个dp数组,不断进行赋值,最后返回dp[n]即可,这种方法可采纳,只不过效率低下,且需要比较高的空间开销。
- 非递归的解法,效率高,空间消耗小,代码已给出。
- 直接求出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;
}
};