一、三数之和
- 题目:
- 解题方法:(排序+双指针)
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int n=nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>>res;
for(int first=0;first<n;first++){
//防止相邻元素相同
if(first>0&&nums[first]==nums[first-1]) continue;
int third =n-1;
int target=-nums[first]; // * + * = - *
for(int second=first+1;second<n;second++){
//防止相邻元素相同
if(second>first+1&&nums[second]==nums[second-1]) continue;
//双指针
while(second<third&&nums[second]+nums[third]>target) third--;
//当双指针位移相同时
if(third==second)break;
//当双指针位移数组值相加等于目标值时
if(nums[second]+nums[third]==target){
res.push_back({nums[first],nums[second],nums[third]});
}
}
}
return res;
}
};
二、最接近的三数之和
- 题目:
- 解题方法:
- 1、排序+双指针
/* class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
/*1、
int n = nums.size(), minDiff = 100000000, ans, temp;
sort(nums.begin(), nums.end());
for(int i = 0; i < n; i++){
for(int j = i + 1, k = n - 1; j < k;){
temp = nums[i] + nums[j] + nums[k];
if(abs(temp - target) < minDiff){
minDiff = abs(temp - target);
ans = temp;
}
if(temp > target){
k--;
}
else if(temp < target){
j++;
}
else{
return ans;
}
}
}
return ans;*/
//2、
sort(nums.begin(), nums.end());
int res = nums[0] + nums[1] + nums[nums.size() - 1];
for (int i = 0; i < nums.size(); ++i)
{
int left = i+1, right = nums.size()-1;
while (left < right)
{
int sum = nums[i] + nums[left] + nums[right];
//相等的话最接近
if (target == sum) return sum;
//比较差的绝对值,取小的,表示更近
if (abs(target-res) > abs(target-sum)) res = sum;
//比目标值小,移动左指针//
if (target > sum) left ++;
else right --;
}
}
return res;
};
- 2、暴力解题
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n=nums.size();
sort(nums.begin(),nums.end());
int res=nums[0]+nums[1]+nums[n-1];
for(int i=0;i<n-2;i++)
for(int j=i+1;j<n-1;j++)
for(int k=j+1;k<n;k++){
int sum = nums[i]+nums[j]+nums[k];
if(abs(target-res)>abs(target-sum)) res=sum;
}
return res;
}
};
三、电话号码的字母组合
- 题目:
- 解题方法:
1、回溯
class Solution {
public:
vector<string> letterCombinations(string str) {
vector<string>strTel;
if(str.empty()) return strTel;
string strOfTel;
backTrack(strTel,phoneMap,str,0,strOfTel);
return strTel;
};
void backTrack(vector<string>&strTel,const unordered_map<char,string>phoneMap, string&str,int index, string&strOfTel){
if(index==str.length()) strTel.push_back(strOfTel);
else{
char c=str[index];
const string&letters=phoneMap.at(c);
for(const char&letter:letters){
strOfTel.push_back(letter);
backTrack(strTel,phoneMap,str,index+1,strOfTel);
strOfTel.pop_back();
}
}
}
private:
unordered_map<char, string> phoneMap{
{'2', "abc"},
{'3', "def"},
{'4', "ghi"},
{'5', "jkl"},
{'6', "mno"},
{'7', "pqrs"},
{'8', "tuv"},
{'9', "wxyz"}
};
};
2、暴力解决
class Solution {
public:
vector<string> letterCombinations(string str) {
if(!str.size()) return {};
if(str.size()==1) return (Tel[str[0]-48-2]);
vector<string>apl;
int n=str.size();
reverse(str.begin(),str.end());
for(int i=0;i<Tel[str[n-1]-48-2].size();i++){
for(int j=0;j<Tel[str[n-2]-48-2].size();j++){
string strNum=Tel[str[n-1]-48-2][i];
strNum+=Tel[str[n-2]-48-2][j];
apl.push_back(strNum);
}
}
if(str.size()==2) return apl;
vector<string>apl3;
for(int i=0;i<apl.size();i++){
for(int j=0;j<Tel[str[n-3]-48-2].size();j++){
string strNum=apl[i];
strNum+=Tel[str[n-3]-48-2][j];
apl3.push_back(strNum);
}
}
if(str.size()==3) return apl3;
vector<string>apl4;
for(int i=0;i<apl3.size();i++){
for(int j=0;j<Tel[str[n-4]-48-2].size();j++){
string strNum=apl3[i];
strNum+=Tel[str[n-4]-48-2][j];
apl4.push_back(strNum);
}
}
if(str.size()==4){
}
return apl4;
}
private:
vector<vector<string>>Tel{
{"a","b","c"},
{"d","e","f"},
{"g","h","i"},
{"j","k","l"},
{"m","n","o"},
{"p","q","r","s"},
{"t","u","v"},
{"w","x","y","z"}
};
};
四、四数之和
- 题目:
- 解题方法
1、双指针
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//双指针
sort(nums.begin(),nums.end());
vector<vector<int>>targetNum;
int n = nums.size();
for(int first=0;first<n;first++){
if(first>0&&nums[first]==nums[first-1]) continue;//闃叉鐩搁偦鍏冪礌閲嶅
int first_num=target-nums[first];
for(int second=first+1;second<n;second++){
if(second>first+1&&nums[second]==nums[second-1])continue;//闃叉鐩搁偦鍏冪礌閲嶅
int second_num=first_num-nums[second];
int four= n-1;
for(int third=second+1;third<n;third++){
if(third>second+1&&nums[third]==nums[third-1])continue;//闃叉鐩搁偦鍏冪礌閲嶅
while(four>third&&nums[four]+nums[third]>second_num) four--;
if(four==third) break;
if(nums[four]+nums[third]==second_num) targetNum.push_back({nums[first],nums[second],nums[third],nums[four]});
}
}
}
return targetNum;
}
};
2、暴力解决(超出限制时间)
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//暴力解题 (超出时间限制)
sort(nums.begin(),nums.end());
int n=nums.size();
vector<vector<int>>res;
for(int first=0;first<n-3;first++){
if(first>0&&nums[first]==nums[first-1]) continue;
for(int second=first+1;second<n-2;second++){
if(second>first+1&&nums[second]==nums[second-1]) continue;
for(int third=second+1;third<n-1;third++){
if(third>second+1&&nums[third]==nums[third-1]) continue;
for(int four=third+1;four<n;four++){
if(four>third+1&&nums[four]==nums[four-1]) continue;
if(nums[first]+nums[second]+nums[third]+nums[four]==target) res.push_back({
nums[first],nums[second],nums[third],nums[four]
});
}
}
}
}
return res;
};
3、回溯
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
//回溯
sort(nums.begin(), nums.end());
myNums = nums;
tar = target;
numSize = nums.size();
if (numSize < 4) {
return ans;
}
DFS(0, 0);
return ans;
}
private:
vector<vector<int>> ans;
vector<int> myNums, subans;
int tar, numSize;
void DFS(int low, int sum) {
if (sum == tar && subans.size() == 4) {
ans.emplace_back(subans);
return;
}
for (int i = low; i < numSize; ++i) {
if (numSize - i < long(4 - subans.size())) { //剪枝
return;
}
if (i > low && myNums[i] == myNums[i - 1]) { //去重
continue;
}
if (i < numSize - 1 && sum + myNums[i] + long(3 - subans.size()) * myNums[i + 1] > tar) { //剪枝
return;
}
if (i < numSize - 1 && sum + myNums[i] + long(3 - subans.size()) * myNums[numSize - 1] < tar) { //剪枝
continue;
}
subans.emplace_back(myNums[i]);
DFS(i + 1, myNums[i] + sum);
subans.pop_back();
}
return;
}
};