1 两数之和 hash表经典题 第四遍写已经很熟练啦
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hash;
vector<int> result;
for (int i=0; i<nums.size(); i++) {
if (hash.find(nums[i])!=hash.end()) {
result.push_back(hash[nums[i]]);
result.push_back(i);
return result;
}
hash[target-nums[i]] = i;
}
return result;
}
};
49 哈希表应用的还是不够熟练 这道题知道用hash但还是用的不好 虽然写出来但超时
正确思路:把所有的str按字母顺序排列 这样异位词会变得一样
在哈希表map中 key是排列好的string 对应的value就是一个vector里面有所有的异位词
最后遍历放入result
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> result;
unordered_map<string, vector<string>> hash;
for (int i=0; i<strs.size(); i++) {
string sorted_str = strs[i];
sort(sorted_str.begin(), sorted_str.end());
hash[sorted_str].push_back(strs[i]);
}
for (pair<string, vector<string>> pair:hash) {
result.push_back(pair.second);
}
return result;
}
};
128 找最长连续序列的长度 先排序 然后看是否连续 如果连续就count++ 反之重新计数
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.size()==0) return 0;
sort(nums.begin(), nums.end());
int result=1;
int count=1;
for (int i=1; i<nums.size(); i++) {
if (nums[i]==nums[i-1]) continue;
if (nums[i]==nums[i-1]+1) count++;
else count=1;
result=max(result,count);
}
return result;
}
};
283 j 找非0的数赋值给 i 指向的元素 最后补0
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i=0;
int j=0;
while (j<nums.size()) {
if (nums[j]==0) j++;
else {
nums[i]=nums[j];
i++;
j++;
}
}
while (i<nums.size()) {
nums[i]=0;
i++;
}
}
};
11 双指针法 指向高度小的指针向中间动 因为当前决定高度的是小的 大的动了宽度变小体积只可能变小 这样可以保证比初始化大的都可以遍历到
class Solution {
public:
int maxArea(vector<int>& height) {
int i=0; int j=height.size()-1;
int result=0;
while (i<j) {
int curr;
if (height[i]<height[j]) {
curr = (j-i)*height[i];
i++;
}
else {
curr = (j-i)*height[j];
j--;
}
result=max(result, curr);
}
return result;
}
};
15 第三次写三数之和 很熟练啦
先排序 遍历第一个数的同时 双指针遍历后两个数 记得去重 发现这一次要做的跟上一个相等就跳过
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> result;
for (int i=0; i<nums.size(); i++) {
if (i!=0 && nums[i]==nums[i-1]) continue;
int j=i+1; int k=nums.size()-1;
while (j<k) {
if (j!=i+1 && nums[j]==nums[j-1]) {
j++;
continue;
}
if (k!=nums.size()-1 && nums[k]==nums[k+1]) {
k--;
continue;
}
if (nums[i]+nums[j]+nums[k]==0) {
vector<int> vec = {nums[i], nums[j], nums[k]};
result.push_back(vec);
j++;
k--;
}
else if (nums[i]+nums[j]+nums[k]<0) j++;
else k--;
}
}
return result;
}
};
42 接雨水问题 这次用双指针自己想出来了!
重点是找左边最大和右边最大 遍历的时候头尾不用管因为一定是0
左最大可以在遍历时更新 因为每次左边只多一个数即height[i-1] 只要看他是否比之前的左最大要大就可以
算出从1到n-1指向的最大值 作为右最大 如果一直height[i]不等于右最大 说明这个最大值还在当前遍历数的右边 如果遇到了就再找一次右最大
遍历到的每一格所积累的雨水是 min(左最大,右最大)比当前高度高出的值 (如果不比当前高则为0 不要加负数)
class Solution {
public:
int trap(vector<int>& height) {
if (height.size()<3) return 0;
int result=0;
int right_height = INT_MIN;
int right =1;
while (right<height.size()) {
right_height = max(right_height, height[right]);
right++;
}
int left_height=height[0];
for (int i=1; i<height.size()-1; i++) {
left_height = max(left_height, height[i-1]);
if (height[i]==right_height) {
right_height = height[i+1];
int right =i+1;
while (right<height.size()) {
right_height = max(right_height, height[right]);
right++;
}
}
if (min(left_height, right_height)-height[i] > 0) {
result += min(left_height, right_height)-height[i];
}
}
return result;
}
};
3 感觉算是暴力解法 先看如果遍历的这个之前set里面没出现就count++ 更新result
如果出现就新set为上次出现之后到当前位置 count重新计数
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int result=0; int count=0;
unordered_set<int> set;
for (int i=0; i<s.size(); i++) {
if (set.find(s[i])==set.end()) {
set.insert(s[i]);
count++;
result=max(result,count);
}
else {
count=1;
int j=i-1;
set.clear();
set.insert(s[i]);
while (j>=0 && s[j]!=s[i]) {
set.insert(s[j]);
count++; j--;
}
}
}
return result;
}
};
438 滑动窗口最主要就是要保留上一次用的元素 这里用一个大小为26的vector来记录每次字母出现的次数 减去滑走的字母 加入计数新加的字母
可以直接比较s_count数组和p_count数组
class Solution {
public:
vector<int> findAnagrams(string s, string p) {
vector<int> result;
if (s.size()<p.size()) return result;
vector<int> p_count(26,0);
vector<int> s_count(26,0);
for (int i=0; i<p.size(); i++) {
p_count[p[i]-'a']++;
s_count[s[i]-'a']++;
}
if (s_count==p_count) result.push_back(0);
for (int i=1; i<s.size()-p.size()+1; i++) {
s_count[s[i-1]-'a']--;
s_count[s[i+p.size()-1]-'a']++;
if (s_count==p_count) {
result.push_back(i);
}
}
return result;
}
};