1.二分法
cpp
class Solution {
public:
int search(vector<int> &nums, int target)
{
int left = 0, right = nums.size() - 1;
while(left <= right) {
int mid = left + ((right - left) >> 1);
if(nums[mid] > target) {
right = mid -1;
} else if(nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
};
2.搜索插入位置
cpp
class Solution {
public:
int searchInsert(vector<int>& nums, int target)
{
int left = 0, right = nums.size() - 1;
while(left <= right) {
int mid = left + ((right - left) >> 1);
if(nums[mid] >= target) {
right = mid -1;
} else if(nums[mid] < target) {
left = mid + 1;
}
}
return left;
}
};
3.搜索第一和最后一个位置
cpp
class Solution {
public:
int binarySearch(vector<int>& nums, int target, bool equ)
{
int left = 0, right = nums.size() - 1;
while(left <= right) {
int mid = left + ((right - left) >> 1);
if(nums[mid] > target || (equ && nums[mid] >= target)) {
right = mid -1;
} else {
left = mid + 1;
}
}
return left;
}
vector<int> searchRange(vector<int>& nums, int target) {
int leftIndex = binarySearch(nums, target, true);
int rightIndex = binarySearch(nums, target, false) - 1;
if(leftIndex <= rightIndex && rightIndex < nums.size() && nums[leftIndex] == target && nums[rightIndex] == target) {
return vector<int>{leftIndex, rightIndex};
}
return vector<int> {-1, -1};
}
};
4.移除元素
cpp
// 快慢指针
class Solution {
public:
int removeElement(vector<int>& nums, int val)
{
int slow = 0, fast = 0;
for( ; fast < nums.size(); ++fast) {
if(nums[fast] != val) {
nums[slow++] = nums[fast];
}
}
return slow;
}
};
// 相向双指针法
class Solution {
public:
int removeElement(vector<int>& nums, int val)
{
int left = 0, right = nums.size() - 1;
while(left <= right) {
while (left <= right && nums[left] != val) {
++left;
}
while (left <= right && nums[right] == val) {
--right;
}
if(left < right) {
nums[left++] = nums[right--];
}
}
return left;
}
};
5.有序数组的平方
cpp
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int left = 0, right = nums.size() -1;
vector<int> result;
while(left <= right) {
long long a = nums[left] * nums[left];
long long b = nums[right] * nums[right];
if (a < b) {
result.push_back(a);
left++;
} else {
result.push_back(b);
right--;
}
}
return result;
}
};
6.长度最小的子数组
cpp
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int result = INT32_MAX;
int start = 0;
int sublength = 0;
int sum = 0;
for(int end = 0; end < nums.size(); end++) {
sum += nums[end];
while(sum >= target) {
sublength = end - start + 1;
result = sublength < result ? sublength : result;
sum -= nums[start++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
7.水果成篮
cpp
class Solution {
public:
int totalFruit(vector<int>& fruits)
{
int start = 0, end = 0, subLength = 0, result = 0;
unordered_map<int, int> um;
for (; end < fruits.size(); end++) {
++um[fruits[end]];
while (um.size() > 2) {
auto it = um.find(fruits[start]);
--it->second;
if (it->second == 0) {
um.erase(it);
}
++start;
}
subLength = end - start + 1;
result = max(result, subLength);
}
return result;
}
};
// 缩小窗口时也可以直接用下标进行减少,通过键值进行删除,
// 需要注意的是,需要减少的是um[fruits[start]]而不是fruits[start]
class Solution {
public:
int totalFruit(vector<int>& fruits) {
int start = 0, end = 0, subLength = 0, result = 0;
unordered_map<int, int> um;
for(; end < fruits.size(); end++) {
++um[fruits[end]];
while(um.size() > 2) {
--um[fruits[start]];
if(um[fruits[start]] == 0) {
um.erase(fruits[start]);
}
++start;
}
subLength = end - start + 1;
result = max(result, subLength);
}
return result;
}
};
8.最长无重复子串
cpp
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_map<char, int> win;
int left = 0,right = 0;
int len = 0;
while(right < s.size()) {
char c = s[right++];
win[c]++;
while(win[c] > 1) {
char d = s[left--];
win[d]--;
}
len = max(len, right - left);
}
return len;
}
};
9.字符串排列
cpp
class Solution {
public:
bool checkInclusion(string s1, string s2) {
unordered_map<char, int>need, win;
for(const char& c : s1) need[c]++;
int left = 0, right = 0;
int valid = 0;
while(right < s2.size()) {
char c = s2[right++];
if(need.count(c)) {
win[c]++;
if(win[c] == need[c]) {
valid++;
}
}
if(right - left == s1.size()) {
if(valid == need.size()) {
return true;
}
char d = s2[left++];
if(need.count(d)) {
if(win[d] == need[d]) {
valid--;
}
win[d]--;
}
}
}
return false;
}
};
10.所有字母异位词
cpp
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
unordered_map<char, int>need, win;
for(const char& c : p) need[c]++;
int left = 0, right = 0;
int valid = 0;
vector<int> res;
while(right < s.size()) {
char c = s[right++];
if(need.count(c)) {
win[c]++;
if(win[c] == need[c]) {
valid++;
}
}
if(right - left == p.size()) {
if(valid == need.size()) {
res.push_back(left);
}
char d = s[left++];
if(need.count(d)) {
if(win[d] == need[d]) {
valid--;
}
win[d]--;
}
}
}
return res;
}
}
11.最小覆盖子串
cpp
class Solution {
public:
string minWindow(string s, string t) {
unordered_map<char, int> need, win;
for(const char& c : t) need[c]++;
int left = 0, right = 0;
int valid = 0;
int start = 0, len = INT32_MAX;
while(right < s.size()) {
char c = s[right++];
if(need.count(c)) {
win[c]++;
if(win[c] == need[c]) {
valid++;
}
}
while(left < right && valid == need.size()) {
if(right - left < len) {
len = right - left;
start = left;
}
char d = s[left++];
if (need.count(d)) {
if(win[d] == need[d]) {
valid--;
}
win[d]--;
}
}
}
return len = = INT32_MAX ? "" : s.substr(start, len);
}
};
12.哈希解法
cpp
class Solution {
public:
string minWindow(string s, string t) {
vector<int>need(128,0); // 定义哈希数组存储,其中ASCII码共有128个符号
for(const char& c : t) {
need[c]++;
}
int left = 0, right = 0;
int valid = t.size();
int start = 0, len = INT32_MAX;
while(right < s.size()) {
char c = s[right++];
if(need[c] > 0) { // 只有need中的元素,才可能大于0,因为right遍历是减少,left最多让元素数量恢复原始大小,而只有need中元素初始为大于0
valid--;
}
need[c]--; // 先把右边的字符加入窗口
if(valid == 0) { // 窗口中已经包含所需的全部字符
while(need[s[left]] < 0) { // 当左边为无效元素或者多余元素(need中过剩的元素)时,缩减窗口
need[s[left]]++;
left++;
} // while循环后,刚好到达一个必不可少的元素
if(right - left < len) { // 更新答案
len = right - left; // 更新最小长度
start = left; // 更新起始位置
}
char d = s[left++];
need[d]++; // 左边界右移之前需要释放need[s[l]]
valid++; // 释放了必要元素,valid增加
}
}
return len == INT32_MAX ? "" : s.substr(start,len);
}
};