1. 两数之和
通过哈希表,来指定两数之和。可以使用map和unorder_map都可以。
vector<int> twoSum(vector<int>& nums,int target)
{
int numsLen = nums.size();
map<int,int> cMap;
vector<int> ans;
for(int i=0;i<numsLen;i++)
{
if(i==0){
cMap[nums[0]]=0;
} else {
if(cMap.count(target-nums[i])!=0)
{
ans.push_back(i);
ans.emplace_back(cMap[target-nums[i]]);
} else {
cMap[nums[i]]=i;
}
}
}
return ans;
}
2. 两数相加
// struct ListNode
// {
// int val;
// ListNode* next;
// ListNode():val(0),next(nullptr){};
// ListNode(int n):val(n),next(nullptr){};
// ListNode(int n,ListNode* ptr):val(n),next(ptr){};
// };
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* headNode = new ListNode;
ListNode* ptr = headNode;
int flag =0;
while(l1 || l2 ||flag)
{
int sum =0;
if(l1&&l2)
{
sum = l1->val+l2->val;
l1=l1->next;
l2=l2->next;
}
else if (l1)
{
sum = l1->val;
l1=l1->next;
}
else if (l2)
{
sum =l2->val;
l2=l2->next;
}
sum=sum+flag;
flag =sum/10;
if(sum>=10) sum =sum%10;
ptr->next = new ListNode(sum);
ptr=ptr->next;
}
ptr =headNode->next;
delete headNode;
return ptr;
}
};
3. 无重复最长子字符串
class Solution {
public:
//lengthOfLongsSubstring 无重复最长子字符串
int lengthOfLongestSubstring(string s) {
//双指针
set<char> cSet;
int len =s.size();
int maxLenSub=0;
int rk =-1;
for(int i=0;i<len;i++)
{
if(i!=0)
{
cSet.erase(s[i-1]);
}
while(rk+1<len&&cSet.count(s[rk+1])==0)
{
cSet.insert(s[rk+1]);
++rk;
}
maxLenSub=max(maxLenSub,rk-i+1);
}
return maxLenSub;
}
};
4. 寻找两个有序数组的中位数
5.最长回文子字符串
解法1,动态规划。
class Solution {
public:
string longestPalindrome(string s) {
string ans;
int size=s.size();
vector<vector<int>> dp(size,vector<int>(size,0));
//初始化数组全部为零
for(int len=1;len<=size;len++)
{
for(int i=0;i<=size-len;i++)
{
int j=i+len-1;
if(len==1)
{
dp[i][j]=1;
}
else if(len==2)
{
dp[i][j]= (s[i]==s[j])?1:0;
}
else
{
dp[i][j] =(s[i]==s[j]&&dp[i+1][j-1])?1:0;
}
if(dp[i][j])
{
ans =s.substr(i,j-i+1);
}
}
}
return ans;
}
};
//解法2,中心扩展法,需要重新补充,写一遍
6. N字形变换
class Solution {
public:
string convert(string s, int numRows) {
//covert 转化
if(numRows==1)
return s;
string ans;
vector<string> cur(numRows);
int index=0;
int flag =1;
for(int i=0;i<s.size();i++)
{
cur[index]+=s[i];
if(index==0) flag=1;
else if(index==numRows-1) flag=-1;
index=index+flag;
}
for(int i=0;i<numRows;i++)
{
ans+=cur[i];
}
return ans;
}
};
7. 整数的反转
class Solution {
public:
int reverse(int x) {
int ans=0;
while(x)
{
if(ans<INT_MIN/10||ans>INT_MAX/10)
return 0;
ans=ans*10+x%10;
x=x/10;
}
return ans;
}
};
8. 字符串转换成整数
class Solution {
public:
int myAtoi(string s) {
int len = s.size();
long long ret = 0;
int flag =1;
int index =0;
//先去掉空白字符,以及判断±
for(int i=0;i<len;i++)
{
if(s[i]==' ')
{
continue;
}
else if(s[i]=='-')
{
flag=-1;
index =i+1;
}
else if(s[i]=='+')
{
flag=1;
index =i+1;
} else
{
index =i;
}
break;
}
for(int i=index;i<len;i++)
{
int cur =0;
if(s[i]>='0'&&s[i]<='9')
{
cur=s[i]-'0';
} else {
break;
}
ret=ret*10+cur;
}
return ret;
};
9. 回文数
class Solution {
public:
bool isPalindrome(int x) {
if(x>=0&&x<10)
{
return true;
}
if(x<0||x%10==0) {
return false;
}
long ret=0;
int x2=x;
while(x2)
{
ret=ret*10+x2%10;
x2=x2/10;
}
return x==ret;
}
};
11.盛最多水的容器
class Solution {
public:
int maxArea(vector<int>& height) {
//双指针可以解决
int size =height.size();
int area = 0;
int left =0;
int right =size-1;
while(left<right)
{
area = max(area,min(height[left],height[right])*(right-left));
if(height[left]<height[right])
{
left++;
}
else
{
right--;
}
}
return area;
}
};
12. 整数转罗马数字
const pair<int, string> valueSymbols[] = {
{1000, "M"},
{900, "CM"},
{500, "D"},
{400, "CD"},
{100, "C"},
{90, "XC"},
{50, "L"},
{40, "XL"},
{10, "X"},
{9, "IX"},
{5, "V"},
{4, "IV"},
{1, "I"},
};
class Solution {
public:
string intToRoman(int num) {
string roman;
for (const auto &[value, symbol] : valueSymbols) {
while (num >= value) {
num -= value;
roman += symbol;
}
if (num == 0) {
break;
}
}
return roman;
}
};
13. 罗马数字转整数
14. 最强公共前缀
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
//查找字符串的公共前缀;
string ret;
int shortlen=0;
for(int i=0;i<strs.size();i++)
{
if(i==0) shortlen=strs[0].size();
else if (shortlen>strs[i].size())
{
shortlen=strs[i].size();
}
}
if(shortlen==0)
return ret;
for(int i=0;i<shortlen;i++)
{
char c=strs[0][i];
for(int j=0;j<strs.size();j++)
{
if(strs[j][i]!=c)
{
return ret;
}
}
ret+=c;
}
return ret;
}
};
15. 三数之和
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
//不能重复
vector<vector<int>> ans;
sort(nums.begin(),nums.end());
for(int first=0;first<nums.size();first++)
{
if(first!=0&&nums[first]==nums[first-1])
{
continue;
}
int third =nums.size()-1;
for(int second=first+1;second<nums.size();second++)
{
if(second!=first+1&&nums[second]==nums[second-1])
{
continue;
}
while(third>second&&nums[first]+nums[second]+nums[third]>0)
{
third--;
}
if(second==third)
{
break;
}
if(nums[first]+nums[second]+nums[third]==0)
{
ans.push_back({nums[first],nums[second],nums[third]});
}
}
}
return ans;
}
};
16. 最接近的三数之和
//这个
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
int best = 1e7;
// 根据差值的绝对值来更新答案
auto update = [&](int cur) {
if (abs(cur - target) < abs(best - target)) {
best = cur;
}
};
// 枚举 a
for (int i = 0; i < n; ++i) {
// 保证和上一次枚举的元素不相等
if (i > 0 && nums[i] == nums[i - 1]) {
continue;
}
// 使用双指针枚举 b 和 c
int j = i + 1, k = n - 1;
while (j < k) {
int sum = nums[i] + nums[j] + nums[k];
// 如果和为 target 直接返回答案
if (sum == target) {
return target;
}
update(sum);
if (sum > target) {
// 如果和大于 target,移动 c 对应的指针
int k0 = k - 1;
// 移动到下一个不相等的元素
while (j < k0 && nums[k0] == nums[k]) {
--k0;
}
k = k0;
} else {
// 如果和小于 target,移动 b 对应的指针
int j0 = j + 1;
// 移动到下一个不相等的元素
while (j0 < k && nums[j0] == nums[j]) {
++j0;
}
j = j0;
}
}
}
return best;
}
};
17.电话号码的字母组合
//回溯法
push
pop
class Solution {
public:
vector<string> letterCombinations(string digits) {
vector<string> ans;
if(digits.size()==0)
return ans;
map<char,string> m={
{'2',"abc"},
{'3',"def"},
{'4',"ghi"},
{'5',"jkl"},
{'6',"mno"},
{'7',"pqrs"},
{'8',"tuv"},
{'9',"wxyz"}
};
string str;
backTrack(m,ans,0,digits,str);
return ans;
}
void backTrack(const map<char,string>& m,vector<string>& ans,int index,string &digits,string str)
{
if(index==digits.size())
{
ans.emplace_back(str);
return;
}
// push
for(int i=0;i<m.at(digits[index]).size();i++)
{
str.push_back(m.at(digits[index])[i]);
backTrack(m,ans,index+1,digits,str);
str.pop_back();
}
//pop
}
};