leetcode刷题记录

1.二分法

class Solution {
public:
    int search(vector &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.搜索插入位置

class Solution {
public:
    int searchInsert(vector& 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.搜索第一和最后一个位置

class Solution {
public:
	int binarySearch(vector& 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 searchRange(vector& 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{leftIndex, rightIndex};
		}
		return vector {-1, -1};
    }
};

4.移除元素

// 快慢指针 
class Solution {
public:
    int removeElement(vector& 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& 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.有序数组的平方

class Solution {
public:
    vector sortedSquares(vector& nums) {
		int left = 0, right = nums.size() -1;
		vector 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.长度最小的子数组

class Solution {
public:
    int minSubArrayLen(int target, vector& 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.水果成篮

class Solution {
public:
    int totalFruit(vector& fruits) 
	{
		int start = 0, end = 0, subLength = 0, result = 0;
		unordered_map 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& fruits) {
		int start = 0, end = 0, subLength = 0, result = 0;
		unordered_map 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.最长无重复子串

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
		unordered_map 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.字符串排列

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
		unordered_mapneed, 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.所有字母异位词

class Solution {
public:
    vector findAnagrams(string s, string p) {
		unordered_mapneed, win;
			for(const char& c : p) need[c]++;
			int left = 0, right = 0;
			int valid = 0;
			vector 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.最小覆盖子串

class Solution {
public:
    string minWindow(string s, string t) {
		unordered_map 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.哈希解法

class Solution {
public:
    string minWindow(string s, string t) {
        vectorneed(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);
    }
};

你可能感兴趣的:(leetcode刷题,leetcode,算法,数据结构)