码迷,mamicode.com
首页 > 其他好文 > 详细

【LeetCode】双指针 two_pointers(共47题)

时间:2019-02-27 01:26:41      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:subarray   遍历   substring   ppi   12月   form   sed   变量   字母   

【3】Longest Substring Without Repeating Characters 

【11】Container With Most Water 

 

【15】3Sum (2019年2月26日)

给了一个乱序的数组,返回一个结果数组,数组里面每个元素是一个三元组, 三元组的和加起来为0。

题解:先固定第一个数,然后后面两个数的控制用夹逼定理,2 pointers 来解。 

技术图片
 1 class Solution {
 2 public:
 3     vector<vector<int>> threeSum(vector<int>& nums) {
 4         const int n = nums.size();
 5         vector<vector<int>> res;
 6         if (nums.size() < 3) {return res;}
 7         sort(nums.begin(), nums.end());
 8         for (int i = 0 ; i < n; ) {
 9             int left = i + 1, right = n - 1;
10             while (left < right) {
11                 int sum = nums[i] + nums[left] + nums[right];
12                 if (sum == 0) {
13                     res.push_back(vector<int>{nums[i], nums[left], nums[right]});
14                     ++left, --right;
15                     while (left < right && nums[left] == nums[left-1]) { ++left; } 
16                     while (left < right && nums[right] == nums[right+1]) { --right; }
17                 } else if (sum < 0) {
18                     ++left;
19                     while (left < right && nums[left] == nums[left-1]) { ++left; } 
20                 } else {
21                     --right;
22                     while (left < right && nums[right] == nums[right+1]) { --right; }
23                 }
24             }
25             ++i;
26             while (i < n && nums[i] == nums[i-1]) {++i;}
27         }
28         return res;
29     }
30 };
View Code

 

【16】3Sum Closest (2019年2月26日)

 

【18】4Sum ()

【19】Remove Nth Node From End of List 

【26】Remove Duplicates from Sorted Array 

【27】Remove Element 

【28】Implement strStr() 

【30】Substring with Concatenation of All Words 

【42】Trapping Rain Water 

【61】Rotate List 

【75】Sort Colors 

 

【76】Minimum Window Substring (2019年1月13日,算法群,第一次写,需要复习)

给了两个字符串 S 和 T, 在S中求一个最短子串,这个字串需要包含 T 中的所有字母。

题解: sliding window, (有两种,窗口大小可变和窗口大小不变的)。用 2 pointers 模拟窗口。时间复杂度是 O(N)。用一个 hash-map mp 记录 t 中的字母频次。用一个 count 变量记录已经满足了的 字母数量。当 mp.size() == count 的时候就可以考虑缩小窗口。https://www.youtube.com/watch?v=9qFR2WQGqkU

技术图片
 1 class Solution {
 2 public:
 3     string minWindow(string s, string t) {
 4         const int ssize = s.size(), tsize = t.size();
 5         if (ssize < tsize) {
 6             return "";
 7         }
 8         unordered_map<char, int> mp;
 9         for (auto c : t) {
10             mp[c]++;
11         }
12         int slow = 0, fast = 0, minLen = INT_MAX, start = 0, count = 0;
13         for (; fast < ssize; ++fast) {
14             char c = s[fast];
15             if (mp.find(c) == mp.end()) {
16                 continue;
17             }
18             mp[c]--;
19             if (mp[c] == 0) { count++; }
20             while (count == mp.size()) {
21                 if (fast - slow + 1 < minLen) {
22                     minLen = fast - slow + 1;
23                     start = slow;
24                 }
25                 char c1 = s[slow++];
26                 if (mp.find(c1) == mp.end()) { continue; }
27                 mp[c1]++;
28                 if (mp[c1] == 1) {
29                     count--;
30                 }
31             }
32         }
33         return minLen == INT_MAX ? "" : s.substr(start, minLen);
34     }
35 };
View Code

 

【80】Remove Duplicates from Sorted Array II 

【86】Partition List 

【88】Merge Sorted Array 

【125】Valid Palindrome 

【141】Linked List Cycle 

【142】Linked List Cycle II 

【159】Longest Substring with At Most Two Distinct Characters 

【167】Two Sum II - Input array is sorted 

 

【209】Minimum Size Subarray Sum (2019年1月11日,算法群)

给了 n 个正整数 nums 数组,和一个正整数 s,要求返回一个最短连续子数组的长度,使得这个子数组的和大于等于s。

follow-up 是 如果想出了 O(n)  的做法,能不能想出 O(nlogn)  的做法。

题解:O(N)  的做法是 2 pointers, O(nlogn) 的做法是 前缀和 + 二分

技术图片
 1 class Solution {
 2 public:
 3     int minSubArrayLen(int s, vector<int>& nums) {
 4         const int n = nums.size();
 5         int p1 = 0, p2 = 0;
 6         int ans = n + 1, cur_sum = 0;
 7         while (p1 <= p2 && p2 < n) {
 8             cur_sum += nums[p2];
 9             while (p1 < p2 && cur_sum - nums[p1] >= s) {
10                 cur_sum -= nums[p1];
11                 ++p1;
12             }
13             if (cur_sum >= s) {
14                 ans = min(p2 - p1 + 1, ans);
15             }
16             ++p2;
17         }
18         return ans == n + 1 ? 0 : ans;
19     }
20 };
View Code

  

【234】Palindrome Linked List 

 

【259】3Sum Smaller (2019年2月26日,谷歌 tag)

给了一个乱序的数组,能不能从中找出三个数,nums[i], nums[j], nums[k] 他们三个想加的和小于target,返回这样三个数的个数。要求时间复杂度是O(N^2)

题解:我想出来的 O(n^2) 的解法是用个map辅助,实时更新map。但是这题的标准解法是先sort,然后先选出一个数,然后剩下两个数用夹逼定理。

技术图片
 1 class Solution {
 2 public:
 3     int threeSumSmaller(vector<int>& nums, int target) {
 4         const int n = nums.size();
 5         sort(nums.begin(), nums.end());
 6         int res(0);
 7         for (int i = 0; i < n; ++i) {
 8             res += twoSumSmaller(nums, i + 1, target - nums[i]);
 9         } 
10         return res;
11     }
12     int twoSumSmaller(vector<int>& nums, int start, int target) {
13         int left = start, right = nums.size() - 1;
14         int res(0);
15         while (left < right) {
16             int sum = nums[left] + nums[right];
17             if (sum < target) {
18                 res += right - left; //包含nums[left]的所有可能解
19                 ++left;
20             } else {
21                 --right;
22             }
23         }
24         return res;
25     }
26 };
View Code

 

【283】Move Zeroes 

 

【287】Find the Duplicate Number 

 

【344】Reverse String (2018年12月3日,第一次review,ko)

逆序一个字符串。

题解:见string分类:https://www.cnblogs.com/zhangwanying/p/9885334.html

 

【345】Reverse Vowels of a String (2018年12月4日,第一次review,ko)

逆序一个字符串的元音字母。

题解:见string分类:https://www.cnblogs.com/zhangwanying/p/9885334.html

 

【349】Intersection of Two Arrays (2018年11月6日,算法群相关题)

hash-table 里面有这题,我就不重复写了。hash-table:https://www.cnblogs.com/zhangwanying/p/9886262.html

 

【350】Intersection of Two Arrays II (2018年11月6日,算法群)

hash-table 里面有这题,我就不重复写了。hash-table:https://www.cnblogs.com/zhangwanying/p/9886262.html

 

【360】Sort Transformed Array 

 

【487】Max Consecutive Ones II (2018年11月27日)

给了一个0/1数组,问如果最多只能把一个 0 变成 1 的话,那么这个数组里面最长的连续 1 有几个?

题解:我是对于每一个 0 都求出了它前面连续 1 的个数 和后面连续 1 的个数。然后再遍历一边原数组,求长度,比较。注意如果全 1 的情况需要考虑。

discuss里面有更好的解法,不用多两个数组。

技术图片
 1 class Solution {
 2 public:
 3     int findMaxConsecutiveOnes(vector<int>& nums) {
 4         const int n = nums.size();
 5         vector<int> pre(n, -1), next(n, -1);
 6         int cnt = 0;
 7         for (int i = 0; i < n; ++i) {
 8             if (nums[i] == 0) {
 9                 pre[i] = cnt;
10                 cnt = 0;
11             } else {
12                 cnt++;
13             }
14         }
15         cnt = 0;
16         for (int i = n-1; i >= 0; --i) {
17             if (nums[i] == 0) {
18                 next[i] = cnt;
19                 cnt = 0;
20             } else {
21                 cnt++;
22             }
23         }
24         int ret = 0;
25         cnt = 0;
26         for (int i = 0; i < n; ++i) {
27             if (nums[i] == 0) {
28                 ret = max(ret, pre[i] + next[i] + 1);
29                 cnt = 0;
30             } else {
31                 cnt++;
32                 ret = max(cnt, ret);
33             }
34         }
35         return ret;
36     }
37 };
View Code

follow-up:What if the input numbers come in one by one as an infinite stream? In other words, you can‘t store all numbers coming from the stream as it‘s too large to hold in memory. Could you solve it efficiently?

 

【524】Longest Word in Dictionary through Deleting 

【532】K-diff Pairs in an Array 

【567】Permutation in String 

【632】Smallest Range 

 

【713】Subarray Product Less Than K (2019年2月11日)

给了一个数组,返回有多少子数组的乘积小于K。

题解:暴力解法O(N^2),2 pointers + sliding window 可以优化到 O(N). 每一步都往移动一个end指针,如果当前的乘积大于等于k了,就往前移动begin指针。计算包含当前end的子数组个数。

技术图片
 1 class Solution {
 2 public:
 3     int numSubarrayProductLessThanK(vector<int>& nums, int k) {
 4         const int n = nums.size();
 5         int begin = 0, end = 0, multi = 1, res = 0;
 6         while (end < n) {
 7             multi = multi * nums[end];
 8             while (begin < end && multi >= k) {
 9                 multi /= nums[begin];
10                 ++begin;
11             }
12             if (multi < k) {
13                 res += (end - begin + 1);
14             }
15             ++end;
16         }
17         return res;
18     }
19 };
View Code

 

【723】Candy Crush 

【763】Partition Labels 

【826】Most Profit Assigning Work 

【828】Unique Letter String 

【838】Push Dominoes 

【844】Backspace String Compare 

【845】Longest Mountain in Array 

【881】Boats to Save People 

 

【LeetCode】双指针 two_pointers(共47题)

标签:subarray   遍历   substring   ppi   12月   form   sed   变量   字母   

原文地址:https://www.cnblogs.com/zhangwanying/p/9886712.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!