71.Unix风格的目录简化
//题目释义摘录自:链接
这道题的要求是简化一个Unix风格下的文件的绝对路径。
字符串处理,由于".."是返回上级目录(如果是根目录则不处理),因此可以考虑用栈记录路径名,以便于处理。需要注意几个细节:
- 重复连续出现的'/',只按1个处理,即跳过重复连续出现的'/';
- 如果路径名是".",则不处理;
- 如果路径名是"..",则需要弹栈,如果栈为空,则不做处理;
- 如果路径名为其他字符串,入栈。
- 最后,再逐个取出栈中元素(即已保存的路径名),用'/'分隔并连接起来,不过要注意顺序呦。
class Solution {
public:
string simplifyPath(string test ) {
string path = test + "/";
vector<string>temp_result;
string result = "/";
int j = 0;
string temp;
for (int i = 0; i<path.size(); ++i) {
if (path[i] == '/') {
temp = path.substr(j, i - j);
j = i + 1;
if (temp.size()>0) {
if (temp == "..") { if(!temp_result.empty())temp_result.pop_back(); }
else if (temp == ".") {}
else { temp_result.push_back(temp); }
}
}
}
for (int i = 0; i < temp_result.size(); ++i)result +=(i==0)? temp_result[i]:("/"+ temp_result[i]);
return result;
}
};
别人的方法//碉堡的getline 用法!!
stringstream用法
auto i: vector用法!!
class Solution {
public:
string simplifyPath(string path ) {
stringstream ss(path);
vector<string>temp_result;
string temp,result;
while(getline(ss,temp,'/')){
if(temp==""||temp==".")continue;
if(temp==".."&!temp_result.empty()){temp_result.pop_back();}
else if(temp!="..")temp_result.push_back(temp);
}
for(auto i:temp_result)result+="/"+i;
return result.empty()?"/":result;
}
};
72.两个单词之间最短距离【一定要再看看】DP问题,迭代的思路!
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)
You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character
只允许插入,删除和替换操作,计算最短步数使得单词1变成单词2
参考别人的思路:
Use f[i][j] to represent the shortest edit distance between word1[0,i) and word2[0, j). Then compare the last character of word1[0,i) and word2[0,j), which are c and d respectively (c == word1[i-1], d == word2[j-1]):
if c == d, then : f[i][j] = f[i-1][j-1]
Otherwise we can use three operations to convert word1 to word2:
(a) if we replaced c with d: f[i][j] = f[i-1][j-1] + 1;
(b) if we added d after c: f[i][j] = f[i][j-1] + 1;
(c) if we deleted c: f[i][j] = f[i-1][j] + 1;
Note that f[i][j] only depends on f[i-1][j-1], f[i-1][j] and f[i][j-1], therefore we can reduce the space to O(n) by using only the (i-1)th array and previous updated element(f[i][j-1]).
class Solution {
public:
int minDistance(string word1, string word2) {
//DP搜索
const int m = word1.size();
const int n = word2.size();
vector<vector<int>>result(m+1, vector<int>(n+1, 0));
for (int i = 0; i < m + 1; i++)result[i][0] = i;
for (int i = 0; i < n + 1; i++)result[0][i] = i;
for (int i = 1; i < m + 1; i++) {
for (int j = 1; j < n + 1; j++) {
if (word1[i - 1] == word2[j - 1])result[i][j] = result[i - 1][j - 1];
else result[i][j] = std::min(result[i - 1][j], std::min(result[i - 1][j - 1], result[i][j - 1]))+1;
}
}
return result[m][n];
}
};
73.设置矩阵0(对应行列改为0)空间限制O(1)
如果某个位置为0,所在的行和列全填充为0.
只允许O(1)的存储空间
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int rows=matrix.size(),cols=matrix[0].size();
int first_col=1,first_row=1;
for(int i=0;i<cols;++i){if(matrix[0][i]==0)first_row=0;}
for(int i=0;i<rows;++i){if(matrix[i][0]==0)first_col=0;}
for(int i=1;i<cols;++i){
for(int j=1;j<rows;++j){
if(matrix[j][i]==0){
matrix[j][0]=0;
matrix[0][i]=0;
}
}
}
for(int j=1;j<rows;j++){
for(int i=1;i<cols;i++){
if(matrix[j][0]==0 || matrix[0][i]==0)matrix[j][i]=0;
}
}
if(first_col==0){for(int i=0;i<rows;++i)matrix[i][0]=0;}
if(first_row==0){for(int i=0;i<cols;++i)matrix[0][i]=0;}
return;
}
};
74.遍历二维排过序的数组
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
- Integers in each row are sorted from left to right.
- The first integer of each row is greater than the last integer of the previous row.
For example,
Consider the following matrix:
[ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ]
我的思路:当成一维的做……用二分查找…
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
if(matrix.size()==0||matrix[0].size()==0)return false;
int m=matrix.size(),n=matrix[0].size();
int left=0,right=m*n-1;
int mid=(left+right)/2;
while(left<right-1){
if(matrix[mid/n][mid%n]==target)return true;
else if(matrix[mid/n][mid%n]>target)right=mid;
else left=mid;
mid=(left+right)/2;
}
if(matrix[left/n][left%n]==target||matrix[right/n][right%n]==target)return true;
return false;
}
};
75.只包含0,1,2三个数字数组的排序
class Solution {
public:
void sortColors(vector<int>& nums) {
unordered_map<int,int>mapping;
for(int i=0;i<nums.size();++i)mapping[nums[i]]++;
for(int i=0;i<mapping[0];++i)nums[i]=0;
for(int i=mapping[0];i<mapping[0]+mapping[1];++i)nums[i]=1;
for(int i=mapping[0]+mapping[1];i<mapping[0]+mapping[1]+mapping[2];++i)nums[i]=2;
return;
}
};
76.包含指定字符的最小字串【Hard】
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC"
.
别人的优雅的代码:
class Solution {
public:
string minWindow(string s, string t) {
vector<int> map(128, 0);
for (auto c : t) map[c]++;//对t编码,每种字符出现次数
int counter = t.size(), begin = 0, end = 0, d = INT_MAX, head = 0;
while (end < s.size()) {//end从头遍历到尾
if (map[s[end++]]-- > 0) counter--; //如果counter为0说明从头到尾包含了所有的
while (counter == 0) { //
if (end - begin < d) d = end - (head = begin);//下一句的begin++保证了d的最小
if (map[s[begin++]]++ == 0) counter++; //make it invalid
}
}
return d == INT_MAX ? "" : s.substr(head, d);
}
};
int findSubstring(string s){
vector<int> map(128,0);
int counter; // check whether the substring is valid
int begin=0, end=0; //two pointers, one point to tail and one head
int d; //the length of substring
for() { /* initialize the hash map here */ }
while(end<s.size()){
if(map[s[end++]]-- ?){ /* modify counter here */ }
while(/* counter condition */){
/* update d here if finding minimum*/
//increase begin to make it invalid/valid again
if(map[s[begin++]]++ ?){ /*modify counter here*/ }
}
/* update d here if finding maximum*/
}
return d;
}
77.1-n中所有k个数字的组合
好久没迭代了,都手生了!!……
//构造一个用以迭代的函数…
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<vector<int>>result;
vector<int>temp;
help(n,k,result,temp,1);
return result;
}
void help(int n,int k,vector<vector<int>>&result,vector<int>&temp,int i){
if(i>n+1)return;
if(temp.size()==k){result.push_back(temp);return;}
temp.push_back(i);help(n,k,result,temp,i+1);
temp.erase(temp.end()-1);help(n,k,result,temp,i+1);
}
};
78.又是一道迭代(2的n次方种)求所有子集
If nums = [1,2,3]
, a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>>result;
vector<int>temp;
help(result,nums,temp,0);
return result;
}
void help(vector<vector<int>>&result,vector<int>&nums,vector<int>&temp,int i){
//if(i>temp.size())return;
if(i==nums.size()){result.push_back(temp);return;}
temp.push_back(nums[i]);help(result,nums,temp,i+1);
temp.erase(temp.end()-1);help(result,nums,temp,i+1);
}
};
79.二维图搜索(不允许走之前走过的路,迭代)Typical dfs+backtracking question(DFS+回溯法)
For example,
Given board =
[ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ]word =
"ABCCED"
, -> returns
true
,
word =
"SEE"
, -> returns
true
,
word =
"ABCB"
, -> returns
false
.
我的方法:89ms...
class Solution {
public:
bool exist(vector<vector<char>>& board, string word) {
if(word=="")return true;
unordered_map<int,int>mapping;
for(int i=0;i<board.size();++i){
for(int j=0;j<board[0].size();++j){
if(board[i][j]==word[0]){
if(help(board,word,1,i,j,mapping))return true;
}
}
}
return false;
}
bool help(vector<vector<char>>board,string word,int i,int m,int n,unordered_map<int,int>&mapping){
if(i==word.size())return true;
mapping[m*board[0].size()+n]=1;
if(m+1<board.size()&&board[m+1][n]==word[i]){if(mapping[(m+1)*board[0].size()+n]!=1&&help(board,word,i+1,m+1,n,mapping))return true;}
if(n+1<board[0].size()&&board[m][n+1]==word[i]){if(mapping[m*board[0].size()+n+1]!=1&&help(board,word,i+1,m,n+1,mapping))return true;}
if(m-1>=0&&board[m-1][n]==word[i]){if(mapping[(m-1)*board[0].size()+n]!=1&&help(board,word,i+1,m-1,n,mapping))return true;}
if(n-1>=0&&board[m][n-1]==word[i]){if(mapping[m*board[0].size()+n-1]!=1&&help(board,word,i+1,m,n-1,mapping))return true;}
mapping[m*board[0].size()+n]=0;
return false;
}
};
别人的DFS+Backtracking,16ms
class Solution {
private:
bool dfs(vector<vector<char>>& board, int row, int col, const string &word, int start, int M, int N, int sLen)
{
char curC;
bool res = false;
if( (curC = board[row][col]) != word[start]) return false;
if(start==sLen-1) return true;
board[row][col] = '*';
if(row>0) res = dfs(board, row-1, col, word, start+1, M, N, sLen);
if(!res && row < M-1) res = dfs(board, row+1, col, word, start+1, M, N, sLen);
if(!res && col > 0) res = dfs(board, row, col-1, word, start+1, M, N, sLen);
if(!res && col < N-1) res = dfs(board, row, col+1, word, start+1, M, N, sLen);
board[row][col] = curC;
return res;
}
public:
bool exist(vector<vector<char>>& board, string word) {
int M,N,i,j,sLen = word.size();
if( (M=board.size()) && (N=board[0].size()) && sLen)
{
for(i=0; i<M; ++i)
for(j=0; j<N; ++j)
if(dfs(board, i, j, word, 0, M, N, sLen)) return true;
}
return false;
}
};
80.sorted数组里保证每个数字至多两次
和26题类似,把多于两个的earse掉就好
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int length=nums.size();//因为nums一直变短,所以需要length,毕竟nums.size()只调用一次
for(int i=0;i<length-2;++i){
if(nums[i]==nums[i+1]&&nums[i]==nums[i+2]){
nums.erase(nums.begin()+i);
--i;--length;
}
}
return nums.size();
}
};
安安静静地陪着建模,233(•‾̑⌣‾̑•)