71. 简化路径
给定一个文档 (Unix-style) 的完全路径,请进行路径简化。
例如,
path = "/home/"
, => "/home"
path = "/a/./b/../../c/"
, => "/c"
边界情况:
- 你是否考虑了 路径 =
"/../"
的情况?
在这种情况下,你需返回"/"
。 - 此外,路径中也可能包含多个斜杠
'/'
,如"/home//foo/"
。
在这种情况下,你可忽略多余的斜杠,返回"/home/foo"
。
class Solution {
public:
string simplifyPath(string path) {
string res,tmp;
vector<string> str;
stringstream s(path);
while(getline(s, tmp, '/')){
if(tmp=="." || tmp=="") continue;
else if(tmp==".."){
if(!str.empty()) str.pop_back();
} else {
str.push_back(tmp);
}
}
for(auto& i:str){
res+="/"+i;
}
return res.empty()? "/":res;
}
};
72. 编辑距离
给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:
- 插入一个字符
- 删除一个字符
- 替换一个字符
示例 1:
输入: word1 = "horse", word2 = "ros"
输出: 3
解释:
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
示例 2:
输入: word1 = "intention", word2 = "execution"
输出: 5
解释:
intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')
class Solution {
public:
int minDistance(string word1, string word2) {
int len1=word1.size(),len2=word2.size();
if(len1==0) return len2;
if(len2==0) return len1;
int dp[len1+1][len2+1];
for(int i=0; i<=len1; i++) dp[i][0]=i;
for(int i=0; i<=len2; i++) dp[0][i]=i;
for(int i=1; i<=len1; i++){
for(int j=1; j<=len2; j++){
if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1];
else dp[i][j]=min(dp[i-1][j-1]+1, min(dp[i-1][j]+1, dp[i][j-1]+1));
}
}
return dp[len1][len2];
}
};
73. 矩阵置零
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。
示例 1:
输入:
[
[1,1,1],
[1,0,1],
[1,1,1]
]
输出:
[
[1,0,1],
[0,0,0],
[1,0,1]
]
示例 2:
输入:
[
[0,1,2,0],
[3,4,5,2],
[1,3,1,5]
]
输出:
[
[0,0,0,0],
[0,4,5,0],
[0,3,1,0]
]
进阶:
- 一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
- 一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
- 你能想出一个常数空间的解决方案吗?
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
if(matrix.empty()) return;
bool col[matrix[0].size()]={false};
for(int i=0; i<matrix.size(); i++){
bool row=false;
for(int j=0; j<matrix[0].size(); j++){
if(matrix[i][j] == 0){
row = true;
col[j] = true;
}
}
if(row){
for(int j=0; j<matrix[0].size(); j++) matrix[i][j]=0;
}
}
for(int j=0; j<matrix[0].size(); j++){
if(col[j]){
for(int i=0; i<matrix.size(); i++) matrix[i][j]=0;
}
}
}
};
74. 搜索二维矩阵
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
- 每行中的整数从左到右按升序排列。
- 每行的第一个整数大于前一行的最后一个整数。
示例 1:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
输出: true
示例 2:
输入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
输出: false
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.empty()) return false;
int row=matrix.size(), col=matrix[0].size();
int left=0, right=row*col;
while(left<right){
int mid=(right-left)/2+left;
int m=mid/col, n=mid%col;
if(matrix[m][n] == target) return true;
else if(matrix[m][n] < target) left=mid+1;
else right=mid;
}
return false;
}
};
75. 颜色分类
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
注意:
不能使用代码库中的排序函数来解决这道题。
示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:
- 一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。 - 你能想出一个仅使用常数空间的一趟扫描算法吗?
class Solution {
public:
void sortColors(vector<int>& nums) {
int zero=0,one=0;
for(int i=0; i<nums.size(); i++){
if(nums[i]==0) zero++;
else if(nums[i]==1) one++;
}
for(int i=0; i<nums.size(); i++){
if(i<zero) nums[i]=0;
else if(i>=(zero+one)) nums[i]=2;
else nums[i]=1;
}
}
};
77. 组合
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
(以上题目均摘自leetcode)