Week1/2 刷题 (7.9 - 7.23)
- 复杂度理论与双指针算法入门
- 必须熟练掌握的两个排序算法
- 二分法
三种双指针算法
- 相向双指针(判断回文串)
- 背向双指针(最长回文串)
- 同向双指针
Valid Palindrome: https://leetcode.com/problems/valid-palindrome/
class Solution {
public:
bool isPalindrome(string s) {
int i = 0;
int j = s.length() - 1;
while (i <= j){
if (tolower(s.at(i)) == tolower(s.at(j))){
i++;
j--;
} else if (!isalpha(s.at(i)) && !isdigit(s.at(i))) {
i++;
} else if (!isalpha(s.at(j)) && !isdigit(s.at(j))) {
j--;
} else {
return false;
}
}
return true;
}
};
记住几个c++的函数: tolower(), toupper() , string.at(), isalpha(), isdigit(),
为什么不是check if (tolower(s.at(i)) != tolower(s.at(j)))呢?
- Valid Palindrome II: https://leetcode.com/problems/valid-palindrome-ii/
Given a string s, return true if the s can be palindrome after deleting at most one character from it.
class Solution {
public:
bool validPalindrome(string s) {
int i = 0;
int j = s.length() - 1;
while (i <= j){
if (s.at(i) == s.at(j)){
i++;
j--;
} else {
return (validPalindromeHelper(s, i+1, j) || validPalindromeHelper(s, i, j-1));
}
}
return true;
}
// Without deleting any character
bool validPalindromeHelper(string s, int i, int j){
while (i <= j){
if (s.at(i) == s.at(j)){
i++;
j--;
} else {
return false;
}
}
return true;
}
};
自己随手写的, 意思是一样的,只是没有上面这个这么精致.
class Solution {
public:
bool validPalindrome(string s) {
if (isPalindrome(s)){
return true;
}
int i = 0;
int j = s.length() - 1;
while (i <= j){
if (s.at(i) == s.at(j)){
i++;
j--;
// delete s.at(i) // delete s.at(j)
} else if (isPalindrome(s.substr(i+1, j-i)) || isPalindrome(s.substr(i, j-i))){
return true;
} else {
return false;
}
}
return true;
}
bool isPalindrome(string s){
int i = 0;
int j = s.length() - 1;
while (i <= j){
if (s.at(i) == s.at(j)){
i++;
j--;
} else {
return false;
}
}
return true;
}
};
像C++的std::string.substr(pos, len) 就跟java是不一样的
string substr (size_t pos = 0, size_t len = npos) const;
Two Sum
brute force就不写了
先是hash map的O(N) time O(N) space的
class Solution {
public:
vector twoSum(vector& nums, int target) {
std::unordered_map map;
vector answer;
for (int i = 0; i < nums.size(); i++){
int needed = target - nums[i];
if (map.find(needed) != map.end()){
answer.push_back(i);
answer.push_back(map[needed]);
return answer;
} else {
map[nums[i]] = i;
}
}
return {-1, -1};
}
};
注意几个std::unordered_map的function:
find()返回的是iterator; count()也可以用; [] operator
std::vector的push_back();
双指针解法: O(NlogN) time O(N) space
不是特别好 排序要O(nlogn)的time,而且因为要存index 还是需要一个map
class Solution {
public:
vector twoSum(vector& nums, int target) {
std::unordered_map indexMap;
for (int i = 0; i < nums.size(); i++){
if (indexMap.find(nums[i]) != indexMap.end()){
if (nums[i] + nums[i] == target){
return {indexMap[nums[i]], i};
}
} else {
indexMap[nums[i]] = i;
}
}
sort(nums.begin(), nums.end());
int i = 0, j = nums.size() - 1;
while (i <= j){
if (nums[i] + nums[j] == target){
return {indexMap[nums[i]], indexMap[nums[j]]};
} else if (nums[i] + nums[j] < target){
i++;
} else {
j--;
}
}
return {-1, -1};
}
};