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

【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 

判断一个循环数组是不是里面是不是含有环,circular array. 

If a number k at an index is positive, then move forward k steps. Conversely, if it’s negative (-k), move backward k steps. Since the array is circular, you may assume that the last element’s next element is the first element, and the first element’s previous element is the last element.

Determine if there is a loop (or a cycle) in nums. A cycle must start and end at the same index and the cycle’s length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of both forward and backward movements.
Could you solve it in O(n) time complexity and O(1) extra space complexity?

题解:快慢指针。这个题目只能沿着一个方向走,所以我们需要判断一下,当前的方向是不是一开始的方向相同,也就是快指针每走一步都要判断一下出发点的数字是不是相同的符号,也就是while循环的部分。

当快慢指针相遇的时候,需要判断一下环的大小是不是1个结点,如果是的话这样是。如果大于一个结点,则返回true。

 1 class Solution {
 2 public:
 3     bool circularArrayLoop(vector<int>& nums) {
 4         const int n = nums.size();
 5         for (int i = 0; i < nums.size(); ++i) {
 6             if (!nums[i]) {continue;}
 7             int slow = i, fast = i;
 8             while (nums[fast] * nums[i] > 0 && nums[getNext(fast, nums)] * nums[i] > 0) {
 9                 slow = getNext(slow, nums), fast = getNext(getNext(fast, nums), nums);
10                 if (slow == fast) {
11                     if (getNext(slow, nums) != slow) { return true; }
12                     else {break;}
13                 }
14             }
15             /*
16             //把走过的slow set成为不能走的状态
17             slow = i;
18             while (nums[slow] * nums[i] > 0) {
19                 nums[slow] = 0;
20                 slow = getNext(slow, nums);
21             }
22             */
23         }
24         return false;
25     }
26     int getNext(int cur, vector<int>& nums) {
27         const int n = nums.size();
28         int res = (nums[cur] + cur) % n;
29         return res < 0 ? res + n : res;
30     }
31 };
View Code

 

【487】Max Consecutive Ones II (2018年11月27日)(2019年3月3日更新)

给了一个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?

2019年3月3日更新,这题和 1004 这周周赛题一模一样,这个是最多能变一个1,1004是是最多能变 k 个 1。解法是 sliding window with 2 pointers。

 1 class Solution {
 2 public:
 3     int findMaxConsecutiveOnes(vector<int>& nums) {
 4         const int n = nums.size();
 5         int start = 0, cnt = 0, res = 0;
 6         for (int i = 0; i < n; ++i) {
 7             if (nums[i] == 0) {cnt++;}
 8             while (cnt > 1) {
 9                 if (nums[start] == 0) {--cnt;}
10                 ++start;
11             }
12             res = max(res, i - start + 1);
13         }
14         return res;
15     }
16 };
View Code

 

【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 (H)(2019年3月5日)

A character is unique in string S if it occurs exactly once in it.

For example, in string S = "LETTER", the only unique characters are "L" and "R".

Let's define UNIQ(S) as the number of unique characters in string S

For example, UNIQ("LETTER") =  2.

Given a string S with only uppercases, calculate the sum of UNIQ(substring) over all non-empty substrings of S.

If there are two or more equal substrings at different positions in S, we consider them different.

Since the answer can be very large, return the answer modulo 10 ^ 9 + 7.

Example 1:
Input: "ABC"
Output: 10
Explanation: All possible substrings are: "A","B","C","AB","BC" and "ABC".
Evey substring is composed with only unique letters.
Sum of lengths of all substring is 1 + 1 + 1 + 2 + 2 + 3 = 10

Example 2:
Input: "ABA"
Output: 8
Explanation: The same as example 1, except uni("ABA") = 1.

Note: 0 <= S.length <= 10000.

题解:hanson solution: https://leetcode.com/problems/unique-letter-string/discuss/ 

 1 class Solution {
 2 public:
 3     const int mod = 1e9+7;
 4     int uniqueLetterString(string S) {
 5         vector<vector<int>> dp(26, vector<int>(2, -1));
 6         int res = 0;
 7         const int n = S.size();
 8         for (int i = 0; i < n; ++i) {
 9             int idx = S[i] - 'A';
10             res = (res + (dp[idx][1] - dp[idx][0]) * (i - dp[idx][1])) % mod;
11             dp[idx][0] = dp[idx][1];
12             dp[idx][1] = i;
13         }
14         for (int i = 0; i < 26; ++i) {
15             res = (res + (dp[i][1] - dp[i][0]) * (n - dp[i][1])) % mod;
16         }
17         return res;
18     }
19 };
View Code

 

【838】Push Dominoes 

【844】Backspace String Compare 

【845】Longest Mountain in Array 

【881】Boats to Save People 

 

转载于:https://www.cnblogs.com/zhangwanying/p/9886712.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值