> 簡潔易懂講清原理,講不清你來打我~
輸入字串,輸出對應整數




簡單的思路
羅馬數字對映整數,遍歷羅馬字串,當第i個對應的字串小於第i+1個,減法,否則加法
精確的定義
RomanToNum是羅馬字元對映數字的雜湊表
i是字串遍歷到的當前下標
ans是羅馬字串對應的最終整數
```cpp
class Solution {
public:
int romanToInt(string s) {
unordered_map<char,int>RomanToNum={
{'I',1},
{'V',5},
{'X',10},
{'L',50},
{'C',100},
{'D',500},
{'M',1000}
};
int ans=0;
for(int i=0;i<s.size();i++){
if(i+1<s.size()&&RomanToNum[s[i+1]]>RomanToNum[s[i]]){
ans-=RomanToNum[s[i]];
}else{
ans+=RomanToNum[s[i]];
}
}
return ans;
}
};
```
> 簡潔易懂講清原理,講不清你來打我~
Leetcode14. 最長公共字首
輸入字串陣列,輸出字串為公共字首


> 暴力
簡單的思路
第一個作為模板,對每個字元陣列進行匹配,對於每個字串,從頭到尾匹配,不能匹配或者超出最右時就不再匹配並更新最右邊界
精確的定義
mostRight是最長公共字首到最右的地方
right是兩字串公共字首最右的地方
i是正在匹配的字串下標
str1是拿來匹配的模板
```cpp
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if(strs.size()==0)return "";
string str1=strs[0];
int mostRight=str1.size();
for(int i=1;i<strs.size();i++){
int right=-1;
while(right+1<strs[i].size()&&right+1<=mostRight&&strs[i][right+1]==str1[right+1]){
right++;
}
mostRight=right;
}
if(mostRight==-1)return "";
return str1.substr(0,mostRight-0+1);
}
};
```
時間複雜度Omn,m是字串平均長度,n是字串數量,最差情況每個字串每個字元都遍歷
1
Leetcode15. 三數之和
陣列找到3個元素,和為0,輸出


詳細思路
sort,先找一個i,剩餘兩個從i右邊開始,用雙指標靠近找出所有滿足的三元組,當i和i-1,left和left-1,right和right+1相同時continue;
精確的定義
i第一個元素下標
left第二個元素下標
right第三個元素下標
ans所有滿足的陣列
```cpp
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>>ans;
if(nums.size()<3)return ans;
sort(nums.begin(),nums.end());
for(int i=0;i<nums.size()-2;i++){
if(i-1>=0&&nums[i]==nums[i-1])continue;
int left=i+1,right=nums.size()-1;
while(left<right){
if(left-1>=i+1&&nums[left]==nums[left-1]){
left++;
continue;
}
else if(right+1<=nums.size()-1&&nums[right]==nums[right+1]){
right--;
continue;
}
if(nums[left]+nums[right]+nums[i]==0){
ans.push_back({nums[i],nums[left],nums[right]});
left++;
right--;
}
else if(nums[left]+nums[right]+nums[i]<0)left++;
else if(nums[left]+nums[right]+nums[i]>0)right--;
}
}
return ans;
}
};
```
踩過的坑
去重
```cpp
if(i-1>=0&&nums[i]==nums[i-1])continue;
if(left-1>=i+1&&nums[left]==nums[left-1]){
left++;
continue;
}
else if(right+1<=nums.size()-1&&nums[right]==nums[right+1]){
right--;
continue;
}
```
Leetcode16. 最接近的三數之和

詳細的思路
sort,對於每一個第一個元素,leftright兩側向中間逼近,儲存最接近的和,絕對值更小的和要儲存,大於的話right--小於的話left++
精確的定義
i第一個元素
left第二個元素
right第三個元素
ans最接近的和
```cpp
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int ans=0x3f3f3f3f;
for(int i=0;i<nums.size()-2;i++){
int left=i+1,right=nums.size()-1;
while(left<right){
ans=abs(nums[i]+nums[left]+nums[right]-target)<abs(ans-target)?nums[i]+nums[left]+nums[right]:ans;
if(nums[i]+nums[left]+nums[right]==target)return target;
else if(nums[i]+nums[left]+nums[right]<target)left++;
else if(nums[i]+nums[left]+nums[right]>target)right--;
}
}
return ans;
}
};
```
踩過的坑
```cpp
int ans=0x3f3f3f3f;
```
Leetcode17. 電話號碼的字母組合



詳細的思路
雜湊表對映數字對應的字串,從第0層開始,找到該層數字對應的字串,遍歷字串,將第一個字元放到陣列並進入下一層,或者不要這個字元而嘗試第二個字元,當層數=最後一個數字也用完了就結束
精確的定義
numToStr雜湊表數字對映字串
depth遞迴層數,也是處理第幾個數字
str該層對應的字串
c字串中的字元
ans1某一種組合
ans所有組合
```cpp
class Solution {
public:
unordered_map<char,string>numToStr={
{'2',"abc"},
{'3',"def"},
{'4',"ghi"},
{'5',"jkl"},
{'6',"mno"},
{'7',"pqrs"},
{'8',"tuv"},
{'9',"wxyz"}
};
vector<string> letterCombinations(string digits) {
if(digits.size()==0)return {};
vector<string>ans;
string ans1;
dfs(digits,ans,ans1,0);
return ans;
}
void dfs(const string&digits,vector<string>&ans,string&ans1,int depth){
if(depth==digits.size()){
ans.push_back(ans1);
return ;
}
string str=numToStr[digits[depth]];
for(auto c:str){
ans1.push_back(c);
dfs(digits,ans,ans1,depth+1);
ans1.pop_back();
}
}
};
```
> 喜歡簡潔易懂還能講清楚原理部落格的小夥伴就關注關注這個非常高產的博主呀,下次再會~