# [15. 3Sum](https://leetcode.com/problems/3sum/)
## Question: (Medium)
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Notice that the order of the output and the order of the triplets does not matter.
Example 2:
Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.
Example 3:
Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.
## Solution: C++
```c=
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
set<vector<int>> set_v;
sort(nums.begin(), nums.end());
int target=0, target2=0;
for(int i=0; i<nums.size(); i++){
target = 0-nums[i];
/* implement two-sum */
int start = i+1;
int end = nums.size()-1;
while(start<end){
int temp = nums[start]+nums[end];
if(temp>target){
end--;
}
else if(temp<target){
start++;
}
else{
vector<int>temp_vector = {nums[i], nums[start], nums[end]};
set_v.insert(temp_vector);
start++;
end--;
}
}
}
vector<vector<int>>ans;
for(auto i=set_v.begin(); i!=set_v.end(); i++){
ans.push_back(*i);
}
return ans;
}
};
```
## Notes
1. We should **sort** this vector in advance.
2. using two-pointer to calculate two-sum.
3. using **C++ stl set<vector<int>>>** to solve this problem.
---
# [125. Valid Palindrome](https://leetcode.com/problems/valid-palindrome/)
## Question : (Easy)
A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.
Given a string s, return true if it is a palindrome, or false otherwise.
Example 1:
Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.
Example 2:
Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.
Example 3:
Input: s = " "
Output: true
Explanation: s is an empty string "" after removing non-alphanumeric characters.
Since an empty string reads the same forward and backward, it is a palindrome.
## Solution: C++
```c=
class Solution {
public:
bool isPalindrome(string s) {
int s_size = s.length();
char* new_str = new char[s_size];
int index = 0;
for(int i=0; i<s_size; i++){
if(s[i]==' ')
continue;
else if(isdigit(s[i]))
new_str[index++]=s[i];
else if(isalpha(s[i]))
new_str[index++]=char(tolower(s[i]));
}
//cout<<new_str<<endl;
if(index==0)
return true;
int start = 0;
int end = index-1;
while(start<end){
if(new_str[start]!=new_str[end]){
return false;
}
else{
start++;
end--;
}
}
return true;
}
};
```
## Notes
1. Using one loop to create new_str;
2. Using two-pointer to check palindrome.
---
# 1679. Max Number of K-Sum Pairs
## Question (Medium)
You are given an integer array nums and an integer k.
In one operation, you can pick two numbers from the array whose sum equals k and remove them from the array.
Return the maximum number of operations you can perform on the array.
Example 1:
Input: nums = [1,2,3,4], k = 5
Output: 2
Explanation: Starting with nums = [1,2,3,4]:
- Remove numbers 1 and 4, then nums = [2,3]
- Remove numbers 2 and 3, then nums = []
There are no more pairs that sum up to 5, hence a total of 2 operations.
Example 2:
Input: nums = [3,1,3,4,3], k = 6
Output: 1
Explanation: Starting with nums = [3,1,3,4,3]:
- Remove the first two 3's, then nums = [1,4,3]
There are no more pairs that sum up to 6, hence a total of 1 operation.
## Solution (C++)
```c=
class Solution {
public:
int maxOperations(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
int start = 0;
int end = nums.size()-1;
int count = 0;
int value = 0;
while(start<end){
value = nums[start] + nums[end];
if(value < k){
start++;
}
else if(value > k){
end--;
}
else{
start++;
end--;
count++;
}
}
return count;
}
};
```
## Notes
* 就是two-pointer,透過nums[start]+nums[end]的數值,來決定pointer移動的方向。
## 1750. Minimum Length of String After Deleting Similar Ends
```cpp=
class Solution {
public:
int minimumLength(string s) {
int start_index = 0;
int end_index = s.length() - 1;
while(start_index <= end_index){
if(start_index == end_index)
return 1;
char temp1 = s[start_index];
char temp2 = s[end_index];
if(temp1!=temp2){
break;
}
else{
while(start_index<s.length()-1 && s[start_index]==temp1){
start_index++;
}
while(end_index>0 && s[end_index]==temp2){
end_index--;
}
}
}
return (start_index>end_index)?0:(end_index-start_index+1);
}
};
```
### Notes:
1. prefix of string: index 0~i的substring
2. suffix of string: index i~end的substring
3. 因此我們有兩個index,分別表示開頭和結尾,用tow pointer的方式來解這題
4. 若s[start_index]==s[end_index]的話表示suffix和prefix的character是一樣的
5. 但我們不知道prefix和suffix各自的長度,所以我們在更新下一次的index時,需要**考慮prefix、suffix的長度**。