From 14905de12c923709ade72c785d093f365bf5ec2c Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 00:09:21 -0700 Subject: [PATCH 01/62] Update Readme.md --- Others/056.Merge-Intervals/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Others/056.Merge-Intervals/Readme.md b/Others/056.Merge-Intervals/Readme.md index 90e3bb855..58b28a487 100644 --- a/Others/056.Merge-Intervals/Readme.md +++ b/Others/056.Merge-Intervals/Readme.md @@ -1,8 +1,8 @@ ### 056.Merge-Intervals -和252类似的解题手法. +对于区间合并的题目,一般都会采用和252类似的"扫描线"算法。对于每一个区间[a,b],我们在a时刻记录+1,在b时刻记录-1. 然后我们再在时间轴上顺次遍历每一个时间点,统计这些+1和-1的总和。我们会发现当sum从0变为正数时,意味着一个merged interval的开始;当sum从正数变成0时,意味着一个merged interval的结束。这样就巧妙地把所有存在overlap的区间都合并到了一起。 -需要注意的是,此题中的有效区间长度可以为0,即[t,t]也是合法的,所以在数组q中,我们除了按时间排序之外,第二指标应该按照先1后-1的次序.即如果遇到相同的时刻,{start,1}要比{end,-1}先进行处理,这样就能顺利地包容[t,t]这样的区间. +需要注意的是,对于相同的时刻,如果同时存在多个+1或者-1,应该先处理+1后处理-1。比如[a,b]和[b,c]两个区间,在处理b时刻时,按照先+1再-1的顺序,就不会出现sum=0的情况了,也就避免了merged interval在b处断开。 -[Leetcode Link](https://leetcode.com/problems/merge-intervals) \ No newline at end of file +[Leetcode Link](https://leetcode.com/problems/merge-intervals) From bf36143690d643efcc5a6ec587d68a9041f3eafa Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 00:51:39 -0700 Subject: [PATCH 02/62] Update Readme.md --- Others/732.My-Calendar-III/Readme.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Others/732.My-Calendar-III/Readme.md b/Others/732.My-Calendar-III/Readme.md index 3e0066e7d..3bd3d1cd3 100644 --- a/Others/732.My-Calendar-III/Readme.md +++ b/Others/732.My-Calendar-III/Readme.md @@ -1,10 +1,7 @@ ### 732.My-Calendar-III -此题有奇思妙解. +典型的扫描线算法。 -我们设计一个顺序的multiset>Set,每次调用我们就往里面放置{start,1}和{end,-1}.然后遍历这个集合,按照从小到大的顺序更新一个计数器,遇到1就加一,遇到-1就减一. +我们用一个按key有序的Map。每次调用book函数时,我们就操作```Map[start]+=1```和```Map[end]-=1```。然后遍历这个Map的key,按照时间轴的顺序累加差分值,即遇到1就加一,遇到-1就减一。这样就得到每个时刻有多少并行的会议。最终输出其中的最大值。 -奇妙的就是,你这样可以实时得到的,就是当前k booking的状态.遍历完之后这个计数器的历史最大值就是答案. - - -[Leetcode Link](https://leetcode.com/problems/my-calendar-iii) \ No newline at end of file +[Leetcode Link](https://leetcode.com/problems/my-calendar-iii) From f4c967f4cd54eb8d242747a14a6f9a3dd528c629 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 00:51:59 -0700 Subject: [PATCH 03/62] Update 732.My-Calendar-III.cpp --- .../732.My-Calendar-III.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Others/732.My-Calendar-III/732.My-Calendar-III.cpp b/Others/732.My-Calendar-III/732.My-Calendar-III.cpp index 1009c4644..413162289 100644 --- a/Others/732.My-Calendar-III/732.My-Calendar-III.cpp +++ b/Others/732.My-Calendar-III/732.My-Calendar-III.cpp @@ -1,6 +1,6 @@ class MyCalendarThree { public: - multiset>Set; + mapMap; MyCalendarThree() { @@ -9,23 +9,23 @@ class MyCalendarThree { int book(int start, int end) { - Set.insert({start,1}); - Set.insert({end,-1}); + Map[start]+=1; + Map[end]-=1; int count=0; - int result=0; - for (auto a: Set) + int ret=0; + for (auto& [t, diff]: Map) { - count+=a.second; - result = max(result,count); + count += diff; + ret = max(ret, count); } - return result; + return ret; } }; /** * Your MyCalendarThree object will be instantiated and called as such: - * MyCalendarThree obj = new MyCalendarThree(); - * int param_1 = obj.book(start,end); + * MyCalendarThree* obj = new MyCalendarThree(); + * int param_1 = obj->book(start,end); */ From 8f0936e8d7fa3a733d8ab8158aaff3cd676a3eb4 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 01:24:00 -0700 Subject: [PATCH 04/62] Update Readme.md --- Others/253.Meeting-Rooms-II/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Others/253.Meeting-Rooms-II/Readme.md b/Others/253.Meeting-Rooms-II/Readme.md index a8a798fb1..38c297c29 100644 --- a/Others/253.Meeting-Rooms-II/Readme.md +++ b/Others/253.Meeting-Rooms-II/Readme.md @@ -16,11 +16,11 @@ 对于pq的数据结构,我们在C++中还可以用multiset来实现,因为它也是自动有序的。 -#### 解法2: +#### 解法2: 扫描线 将所有{startTime,1}和{endTime,-1}加入一个数组,然后将这个数组按照时间戳排序.注意,本题中所有的有效区间的长度必须大于0,所以,{time,-1}要比{time,1}排序更靠前. 使用一个count依时间顺序将所有的+1/-1进行累加.当count>0的时候标志着一个会议的开始,重新归为0的时候标着一个会议的结束. -[Leetcode Link](https://leetcode.com/problems/meeting-rooms-ii) \ No newline at end of file +[Leetcode Link](https://leetcode.com/problems/meeting-rooms-ii) From 4f2379f0b6c963f29abf6c1f2f5ad8ef8417334c Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 01:32:19 -0700 Subject: [PATCH 05/62] Update 253.Meeting-Rooms-II_v2.cpp --- .../253.Meeting-Rooms-II_v2.cpp | 44 +++++++------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/Others/253.Meeting-Rooms-II/253.Meeting-Rooms-II_v2.cpp b/Others/253.Meeting-Rooms-II/253.Meeting-Rooms-II_v2.cpp index f1ea07acb..a4763c5ea 100644 --- a/Others/253.Meeting-Rooms-II/253.Meeting-Rooms-II_v2.cpp +++ b/Others/253.Meeting-Rooms-II/253.Meeting-Rooms-II_v2.cpp @@ -1,34 +1,20 @@ -/** - * Definition for an interval. - * struct Interval { - * int start; - * int end; - * Interval() : start(0), end(0) {} - * Interval(int s, int e) : start(s), end(e) {} - * }; - */ class Solution { - static bool cmp1(Interval a, Interval b) - { - return a.start& intervals) - { - sort(intervals.begin(),intervals.end(),cmp1); - multisetSet; - int count=0; - int i=0; - while (iintervals[i].start) - { - Set.insert(intervals[i].end); - count = max(count,int(Set.size())); - i++; - } - Set.erase(Set.begin()); + int minMeetingRooms(vector>& intervals) { + mapMap; + for (auto interval:intervals) + { + Map[interval[0]]+=1; + Map[interval[1]]-=1; + } + + int sum = 0; + int ret = 0; + for (auto& [t,diff]: Map) + { + sum += diff; + ret = max(sum, ret); } - return count; + return ret; } }; From 6b48384833ce75c159163be0f9314d12da0c1513 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 01:33:04 -0700 Subject: [PATCH 06/62] Update Readme.md --- Others/253.Meeting-Rooms-II/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Others/253.Meeting-Rooms-II/Readme.md b/Others/253.Meeting-Rooms-II/Readme.md index 38c297c29..78e72ed80 100644 --- a/Others/253.Meeting-Rooms-II/Readme.md +++ b/Others/253.Meeting-Rooms-II/Readme.md @@ -18,7 +18,7 @@ #### 解法2: 扫描线 -将所有{startTime,1}和{endTime,-1}加入一个数组,然后将这个数组按照时间戳排序.注意,本题中所有的有效区间的长度必须大于0,所以,{time,-1}要比{time,1}排序更靠前. +本题和732一模一样。将所有{startTime,1}和{endTime,-1}加入一个数组,然后将这个数组按照时间戳排序.注意,本题中所有的有效区间的长度必须大于0,所以,{time,-1}要比{time,1}排序更靠前. 使用一个count依时间顺序将所有的+1/-1进行累加.当count>0的时候标志着一个会议的开始,重新归为0的时候标着一个会议的结束. From 0e98ccd41a47e0201b570d7106091a4d892567bb Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 01:33:35 -0700 Subject: [PATCH 07/62] Update Readme.md --- Others/732.My-Calendar-III/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Others/732.My-Calendar-III/Readme.md b/Others/732.My-Calendar-III/Readme.md index 3bd3d1cd3..e91eecae4 100644 --- a/Others/732.My-Calendar-III/Readme.md +++ b/Others/732.My-Calendar-III/Readme.md @@ -1,6 +1,6 @@ ### 732.My-Calendar-III -典型的扫描线算法。 +本题和253一模一样。典型的扫描线算法。 我们用一个按key有序的Map。每次调用book函数时,我们就操作```Map[start]+=1```和```Map[end]-=1```。然后遍历这个Map的key,按照时间轴的顺序累加差分值,即遇到1就加一,遇到-1就减一。这样就得到每个时刻有多少并行的会议。最终输出其中的最大值。 From 4674eea93c4d46d133e8192d91f061623b2581e3 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 17:54:27 -0700 Subject: [PATCH 08/62] Create 2272.Substring-With-Largest-Variance.cpp --- .../2272.Substring-With-Largest-Variance.cpp | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance.cpp diff --git a/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance.cpp b/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance.cpp new file mode 100644 index 000000000..7b91e9785 --- /dev/null +++ b/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance.cpp @@ -0,0 +1,52 @@ +class Solution { +public: + int largestVariance(string s) + { + vectorcount(26,0); + for (auto x: s) + count[x-'a']++; + + int ret = 0; + int n = s.size(); + for (int i=0; i<26; i++) + for (int j=0; j<26; j++) + { + if (i==j) continue; + if (count[i]==0 || count[j]==0) continue; + vectorarr(n, 0); + for (int k=0; k&nums) + { + int n = nums.size(); + vectordp(n); + int curSum = 0; + + for (int i = 0; i < n; i++) + { + curSum = max(curSum+nums[i], nums[i]); + dp[i] = curSum; + } + + curSum = 0; + int ret = 0; + for (int i=n-1; i>=0; i--) + { + curSum = max(curSum+nums[i], nums[i]); + if (nums[i]==-1) + ret = max(ret, curSum + dp[i] - nums[i]); + } + return ret; + } +}; From 1c66e00e15f162d94c79c74e102bc9c264937350 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 17:58:08 -0700 Subject: [PATCH 09/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index d4f5d6b98..fe01b0db3 100644 --- a/Readme.md +++ b/Readme.md @@ -609,6 +609,7 @@ [2140.Solving-Questions-With-Brainpower](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2140.Solving-Questions-With-Brainpower) (H) [2189.Number-of-Ways-to-Build-House-of-Cards](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2189.Number-of-Ways-to-Build-House-of-Cards) (H-) [2218.Maximum-Value-of-K-Coins-From-Piles](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2218.Maximum-Value-of-K-Coins-From-Piles) (H-) +[2272.Substring-With-Largest-Variance](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2272.Substring-With-Largest-Variance) (H-) * ``基本型 I`` [198.House-Robber](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/198.House-Robber) (E) [213.House-Robber-II](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/213.House-Robber-II) (M+) From af821e345ace1e2bf18e22c75bd18932745c8a04 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 18:08:47 -0700 Subject: [PATCH 10/62] Create Readme.md --- .../2272.Substring-With-Largest-Variance/Readme.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md diff --git a/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md new file mode 100644 index 000000000..7b3f197d3 --- /dev/null +++ b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md @@ -0,0 +1,7 @@ +### 2272.Substring-With-Largest-Variance + +本题的突破口是数据范围n=1e4.这是一个比较奇怪的数字。通常来说如果允许nlogn的复杂度,那么n可以达到1e5;类似的,如果是n^2的复杂度,那么n大概就是1000. 在这里,很可能是一个大概是存在100的常数k,使得复杂度的限制在o(kn)。于是我们大概可以猜到,这个k就是跟26或者26^2相关,也就是英文字母的个数。 + +于是我们就想到了穷举本题中的最大频次字符x和最小频次字母y。这样的话,我们需要在原字符串里面找一个滑窗,使得x的频次与y的频次之差最大,而其他字母都没有任何作用。这就联想到,如果将x的字符都替换为1,y的字符都替换为-1,其他字符都替换为0,那么不就是变成了寻找```max subarray sum```的题目了吗? + +但是注意,这里有一点不同,根据题意,我们想要找的subarray必须至少包含一个-1. 传统的kadane算法,我们很有可能找出只有+1的subarray。那么怎么办呢?我们可以找那个-1为突破口。根据Kadane的思想,我们找到以每个元素为结尾的最大subarray sum记做dp1[i],那么反过来走一遍就可以得到以每个元素为开头的最大subarray sum记做dp2[i]。那么我们再遍历所有的-1元素i,那么dp1[i]+dp2[i]-nums[i]必然是包含了至少一个-1的max subarray sum。我们再全局找一个最大值即可。 From 63cba9294ccd602e21c400f1ae69f67f6691a419 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 18:39:05 -0700 Subject: [PATCH 11/62] Update Readme.md --- Readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index fe01b0db3..e91adede2 100644 --- a/Readme.md +++ b/Readme.md @@ -578,9 +578,7 @@ [221.Maximal-Square](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/221.Maximal-Square) (H-) [1277.Count-Square-Submatrices-with-All-Ones](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/1277.Count-Square-Submatrices-with-All-Ones) (M+) [600.Non-negative-Integers-without-Consecutive-Ones](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/600.Non-negative-Integers-without-Consecutive-Ones) (H) -[656.Coin-Path](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/656.Coin-Path) (H-) -[053.Maximum-Subarray](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/053.Maximum-Subarray) (E+) -[152.Maximum-Product-Subarray](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/152.Maximum-Product-Subarray) (M+) +[656.Coin-Path](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/656.Coin-Path) (H-) [818.Race-Car](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/818.Race-Car) (H) [377.Combination-Sum-IV](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/377.Combination-Sum-IV) (M) [837.New-21-Game](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/837.New-21-Game) (H-) @@ -609,7 +607,6 @@ [2140.Solving-Questions-With-Brainpower](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2140.Solving-Questions-With-Brainpower) (H) [2189.Number-of-Ways-to-Build-House-of-Cards](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2189.Number-of-Ways-to-Build-House-of-Cards) (H-) [2218.Maximum-Value-of-K-Coins-From-Piles](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2218.Maximum-Value-of-K-Coins-From-Piles) (H-) -[2272.Substring-With-Largest-Variance](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2272.Substring-With-Largest-Variance) (H-) * ``基本型 I`` [198.House-Robber](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/198.House-Robber) (E) [213.House-Robber-II](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/213.House-Robber-II) (M+) @@ -764,6 +761,10 @@ [1866.Number-of-Ways-to-Rearrange-Sticks-With-K-Sticks-Visible](https://github.com/wisdompeak/LeetCode/tree/master/Math/1866.Number-of-Ways-to-Rearrange-Sticks-With-K-Sticks-Visible) (H) * ``Infer future from current`` [2044.Count-Number-of-Maximum-Bitwise-OR-Subsets](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2044.Count-Number-of-Maximum-Bitwise-OR-Subsets) (M) +* ``max subarray`` +[053.Maximum-Subarray](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/053.Maximum-Subarray) (E+) +[152.Maximum-Product-Subarray](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/152.Maximum-Product-Subarray) (M+) +[2272.Substring-With-Largest-Variance](https://github.com/wisdompeak/LeetCode/tree/master/Dynamic_Programming/2272.Substring-With-Largest-Variance) (H-) #### [Bit Manipulation](https://github.com/wisdompeak/LeetCode/tree/master/Bit_Manipulation) [137.Single-Number-II](https://github.com/wisdompeak/LeetCode/tree/master/Bit_Manipulation/137.Single-Number-II) (H-) From ed7bc1ec4d881017c7403794eb812ea32412dcb8 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 20:41:51 -0700 Subject: [PATCH 12/62] Update 493.Reverse-Pairs_v1.cpp --- .../493.Reverse-Pairs_v1.cpp | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/Divide_Conquer/493.Reverse-Pairs/493.Reverse-Pairs_v1.cpp b/Divide_Conquer/493.Reverse-Pairs/493.Reverse-Pairs_v1.cpp index 0131dfb07..19ac47544 100644 --- a/Divide_Conquer/493.Reverse-Pairs/493.Reverse-Pairs_v1.cpp +++ b/Divide_Conquer/493.Reverse-Pairs/493.Reverse-Pairs_v1.cpp @@ -21,36 +21,38 @@ class Solution { auto iter = upper_bound(sorted.begin()+a, sorted.begin()+mid+1, 2*(long)nums[j]); ret += sorted.begin()+mid+1 - iter; } - // sort(sorted.begin()+a, sorted.begin()+b+1); - int i=a, j=mid+1, p = 0; - while (i<=mid && j<=b) - { - if (sorted[i]<=sorted[j]) - { - temp[p] = sorted[i]; - i++; - } - else - { - temp[p] = sorted[j]; - j++; - } - p++; - } - while (i<=mid) - { - temp[p] = sorted[i]; - i++; - p++; - } - while (j<=b) - { - temp[p] = sorted[j]; - j++; - p++; - } - for (int i=0; i Date: 2022年5月14日 23:41:35 -0700 Subject: [PATCH 13/62] Create 2272.Substring-With-Largest-Variance_v2.cpp --- ...272.Substring-With-Largest-Variance_v2.cpp | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance_v2.cpp diff --git a/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance_v2.cpp b/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance_v2.cpp new file mode 100644 index 000000000..9180ed22d --- /dev/null +++ b/Dynamic_Programming/2272.Substring-With-Largest-Variance/2272.Substring-With-Largest-Variance_v2.cpp @@ -0,0 +1,55 @@ +class Solution { +public: + int largestVariance(string s) + { + vectorcount(26,0); + for (auto x: s) + count[x-'a']++; + + int ret = 0; + int n = s.size(); + for (int i=0; i<26; i++) + for (int j=0; j<26; j++) + { + if (i==j) continue; + if (count[i]==0 || count[j]==0) continue; + vectorarr(n, 0); + for (int k=0; k&nums) + { + int n = nums.size(); + int curSum0 = 0; + int curSum1 = INT_MIN/2; + int ret = 0; + + for (int i = 0; i < n; i++) + { + if (nums[i]==1) + { + curSum1 = curSum1+nums[i]; + curSum0 = max(curSum0+nums[i], nums[i]); + } + else if (nums[i] == -1) + { + curSum1 = max(nums[i], max(curSum0, curSum1)+nums[i]); + curSum0 = 0; + } + + ret = max(ret, curSum1); + } + + return ret; + } +}; From c3ede06398a10c795d316ab1a519e499f81e9bd0 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 23:44:22 -0700 Subject: [PATCH 14/62] Update Readme.md --- .../Readme.md | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md index 7b3f197d3..a6723c0a2 100644 --- a/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md +++ b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md @@ -4,4 +4,28 @@ 于是我们就想到了穷举本题中的最大频次字符x和最小频次字母y。这样的话,我们需要在原字符串里面找一个滑窗,使得x的频次与y的频次之差最大,而其他字母都没有任何作用。这就联想到,如果将x的字符都替换为1,y的字符都替换为-1,其他字符都替换为0,那么不就是变成了寻找```max subarray sum```的题目了吗? -但是注意,这里有一点不同,根据题意,我们想要找的subarray必须至少包含一个-1. 传统的kadane算法,我们很有可能找出只有+1的subarray。那么怎么办呢?我们可以找那个-1为突破口。根据Kadane的思想,我们找到以每个元素为结尾的最大subarray sum记做dp1[i],那么反过来走一遍就可以得到以每个元素为开头的最大subarray sum记做dp2[i]。那么我们再遍历所有的-1元素i,那么dp1[i]+dp2[i]-nums[i]必然是包含了至少一个-1的max subarray sum。我们再全局找一个最大值即可。 +但是注意,这里有一点不同,根据题意,我们想要找的subarray必须至少包含一个-1. 传统的kadane算法,我们很有可能找出只有+1的subarray。那么怎么办呢?有两种方法。 + +#### 解法1 +我们可以找那个-1为突破口。根据Kadane的思想,我们找到以每个元素为结尾的最大subarray sum记做dp1[i],那么反过来走一遍就可以得到以每个元素为开头的最大subarray sum记做dp2[i]。那么我们再遍历所有的-1元素i,那么dp1[i]+dp2[i]-nums[i]必然是包含了至少一个-1的max subarray sum。我们再全局找一个最大值即可。 + +#### 解法2 +我们依然按照kadane算法的思路,但是设置两个临时变量curSum0表示以当前元素为结尾、不包含-1的最大subarray sum,另外用curSum1表示以当前元素为结尾、已经包含-1的最大subarray sum。转移方程如下: +```cpp + for (int i = 0; i < n; i++) + { + if (nums[i] == 1) + { + curSum1 = curSum1+nums[i]; + curSum0 = max(curSum0+nums[i], nums[i]); + } + else if (nums[i] == -1) + { + curSum1 = max(nums[i], max(curSum0, curSum1)+nums[i]); + curSum0 = 0; + } + + ret = max(ret, curSum1); + } +``` +特别注意,curSum0的初始值可以是0,但是curSum1的初始值必须设置为INT_MIN. From e22071ec7dd8addb957945b8c1d8edd10bc40112 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月14日 23:46:28 -0700 Subject: [PATCH 15/62] Update Readme.md --- .../2272.Substring-With-Largest-Variance/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md index a6723c0a2..fcfaa211b 100644 --- a/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md +++ b/Dynamic_Programming/2272.Substring-With-Largest-Variance/Readme.md @@ -10,7 +10,7 @@ 我们可以找那个-1为突破口。根据Kadane的思想,我们找到以每个元素为结尾的最大subarray sum记做dp1[i],那么反过来走一遍就可以得到以每个元素为开头的最大subarray sum记做dp2[i]。那么我们再遍历所有的-1元素i,那么dp1[i]+dp2[i]-nums[i]必然是包含了至少一个-1的max subarray sum。我们再全局找一个最大值即可。 #### 解法2 -我们依然按照kadane算法的思路,但是设置两个临时变量curSum0表示以当前元素为结尾、不包含-1的最大subarray sum,另外用curSum1表示以当前元素为结尾、已经包含-1的最大subarray sum。转移方程如下: +我们依然按照kadane算法的思路,但是设置两个临时变量:curSum0表示以当前元素为结尾、不包含-1的最大subarray sum,另外用curSum1表示以当前元素为结尾、已经包含-1的最大subarray sum。转移方程如下: ```cpp for (int i = 0; i < n; i++) { @@ -21,8 +21,8 @@ } else if (nums[i] == -1) { - curSum1 = max(nums[i], max(curSum0, curSum1)+nums[i]); - curSum0 = 0; + curSum1 = max(nums[i], max(curSum0, curSum1)+nums[i]); // 三种情况可以转移到新的curSum1 + curSum0 = 0; // 因为nums[i]是-1,curSum0没有意义,只能置零 } ret = max(ret, curSum1); From 91f879aa9965da37db745a239524b7e9faadadee Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 00:39:33 -0700 Subject: [PATCH 16/62] Create 2271.Maximum-White-Tiles-Covered-by-a-Carpet.cpp --- ...aximum-White-Tiles-Covered-by-a-Carpet.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/2271.Maximum-White-Tiles-Covered-by-a-Carpet.cpp diff --git a/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/2271.Maximum-White-Tiles-Covered-by-a-Carpet.cpp b/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/2271.Maximum-White-Tiles-Covered-by-a-Carpet.cpp new file mode 100644 index 000000000..36b4f7ca4 --- /dev/null +++ b/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/2271.Maximum-White-Tiles-Covered-by-a-Carpet.cpp @@ -0,0 +1,26 @@ +class Solution { + vectorpresum; +public: + int maximumWhiteTiles(vector>& tiles, int carpetLen) + { + sort(tiles.begin(), tiles.end()); + int n = tiles.size(); + presum.resize(n); + for (int i=0; i= tiles[j][1]) + j++; + int len = presum[j-1] - (i==0?0:presum[i-1]); + if (j Date: 2022年5月15日 00:40:04 -0700 Subject: [PATCH 17/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index e91adede2..8ce955e2c 100644 --- a/Readme.md +++ b/Readme.md @@ -1081,6 +1081,7 @@ [2233.Maximum-Product-After-K-Increments](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2233.Maximum-Product-After-K-Increments) (M+) [2234.Maximum-Total-Beauty-of-the-Gardens](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2234.Maximum-Total-Beauty-of-the-Gardens) (H-) [2257.Count-Unguarded-Cells-in-the-Grid](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2257.Count-Unguarded-Cells-in-the-Grid) (M+) +[2271.Maximum-White-Tiles-Covered-by-a-Carpet](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet) (M+) * ``LIS`` [300.Longest-Increasing-Subsequence](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/300.Longest-Increasing-Subsequence) (M+) [354.Russian-Doll-Envelopes](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/354.Russian-Doll-Envelopes) (H-) From 54578182e39a19ba5142afee64dc2cb4d8ded540 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 00:57:54 -0700 Subject: [PATCH 18/62] Create Readme.md --- .../Readme.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/Readme.md diff --git a/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/Readme.md b/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/Readme.md new file mode 100644 index 000000000..8b85a0e52 --- /dev/null +++ b/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet/Readme.md @@ -0,0 +1,15 @@ +### 2271.Maximum-White-Tiles-Covered-by-a-Carpet + +本题有非常直观的一种方案。我们放毯子,必然会把毯子的左边界和某一段tile的左边界对齐,以最大化毯子的覆盖(或者说最小化毯子的浪费)。假想我们把毯子的左边界与某tile的中段对齐,直觉上我们不妨将毯子再往左边拉一拉:这个过程中我们本质上,挪用了一部分毯子右侧的空间来覆盖了左边一部分瓷砖,而这个操作肯定是不亏的,甚至还可能赚(因为毯子右侧有可能覆盖的是空隙)。 + +所以本题我们只要逐一考察毯子的左边界应该对齐哪个tile的左边界即可。在这个过程中,毯子的右边界的位置自然也是单调递增的。所以本题就是维护一个双指针的滑窗。 + +假设毯子的左边界对应的是tiles[i][0],那么我们向右移动指针j来定位毯子右边界解出的是哪个tile,直至```tiles[i][0]+carpetLen-1 < tiles[j][1]```。如图 +``` +carpet ____________________________ + tiles _____ ________ ________ _______ + i j +``` +此时tiles[i: j-1]这部分的瓷砖是完全被覆盖的,我们可以用前缀和之差来计算这些tiles的瓷砖总数。另外我们需要计算第j个tile被额外覆盖了多少,这也容易得到:```tiles[i][0]+carpetLen-1 - tiles[j][0] + 1```. 两部分相加就是地毯在这个位置的覆盖面积。 + +随着地毯移动n次,取全局的最大值即可。 From cc1fd3d1b92c342d0691e822439c1d96e401ce1d Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 16:06:14 -0700 Subject: [PATCH 19/62] Create 2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero.cpp --- ...tion-With-Bitwise-AND-Greater-Than-Zero.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero.cpp diff --git a/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero.cpp b/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero.cpp new file mode 100644 index 000000000..1ba06cb5e --- /dev/null +++ b/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero.cpp @@ -0,0 +1,18 @@ +class Solution { +public: + int largestCombination(vector& candidates) + { + int ret = 0; + for (int i=0; i<31; i++) + { + int count = 0; + for (int x: candidates) + { + if ((x>>i)&1) + count++; + } + ret = max(ret, count); + } + return ret; + } +}; From b4faf372b6fb3df264108f089c0a874b54ff55fa Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 16:06:42 -0700 Subject: [PATCH 20/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 8ce955e2c..40e48bbd0 100644 --- a/Readme.md +++ b/Readme.md @@ -1082,6 +1082,7 @@ [2234.Maximum-Total-Beauty-of-the-Gardens](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2234.Maximum-Total-Beauty-of-the-Gardens) (H-) [2257.Count-Unguarded-Cells-in-the-Grid](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2257.Count-Unguarded-Cells-in-the-Grid) (M+) [2271.Maximum-White-Tiles-Covered-by-a-Carpet](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2271.Maximum-White-Tiles-Covered-by-a-Carpet) (M+) +[2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero) (M+) * ``LIS`` [300.Longest-Increasing-Subsequence](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/300.Longest-Increasing-Subsequence) (M+) [354.Russian-Doll-Envelopes](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/354.Russian-Doll-Envelopes) (H-) From f2d87dd927437a56b9871299d4de708c31c1f6ad Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 17:14:54 -0700 Subject: [PATCH 21/62] Create Readme.md --- .../Readme.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/Readme.md diff --git a/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/Readme.md b/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/Readme.md new file mode 100644 index 000000000..56f6d44c1 --- /dev/null +++ b/Greedy/2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero/Readme.md @@ -0,0 +1,5 @@ +### 2275.Largest-Combination-With-Bitwise-AND-Greater-Than-Zero + +将若干个数Bitwise AND之后的结果S如果不为零,说明S至少有一个bit位不为零,也就是说所有的数在该bit位上不能有0存在。于是我们可以检查每个bit,统计有多少元素在该bit位上非零。假设有M个元素在某个二进制位上都是1,那么他们的AND结果必然就不是零。 + +显然,对于32bit的整形,我们检查每个位置之后,可以找到这样一个最大的M。但M是否是最终的答案呢,有没有可能更多呢?答案是否定的。如果有M+1个元素的AND结果非零,必然有一个bit位上该M+1个元素都非零。这和之前的假设"M是所有bit位上我们找到的非零元素最多的那个"相矛盾。 From 646a39953fe3bb755b036fa4066c4974f69fb71c Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:15:29 -0700 Subject: [PATCH 22/62] Create 2276.Count-Integers-in-Intervals.cpp --- .../2276.Count-Integers-in-Intervals.cpp | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Heap/2276.Count-Integers-in-Intervals/2276.Count-Integers-in-Intervals.cpp diff --git a/Heap/2276.Count-Integers-in-Intervals/2276.Count-Integers-in-Intervals.cpp b/Heap/2276.Count-Integers-in-Intervals/2276.Count-Integers-in-Intervals.cpp new file mode 100644 index 000000000..603350629 --- /dev/null +++ b/Heap/2276.Count-Integers-in-Intervals/2276.Count-Integers-in-Intervals.cpp @@ -0,0 +1,52 @@ +class CountIntervals { + mapMap; + int ret = 0; +public: + CountIntervals() { + + } + + void add(int left, int right) + { + unordered_settemp; + + int start = left; + auto iter = Map.lower_bound(left); + if (iter!=Map.begin() && prev(iter)->second>=start) + { + iter = prev(iter); + temp.insert(iter->first); + start = min(start, iter->first); + } + + int end = right; + iter = Map.lower_bound(left); + if (iter!=Map.begin()) + end = max(end, prev(iter)->second); + while (iter!=Map.end() && iter->first<=end) + { + temp.insert(iter->first); + end = max(end, iter->second); + iter = next(iter); + } + + for (int x: temp) + { + ret -= Map[x]-x+1; + Map.erase(x); + } + ret += end-start+1; + Map[start] = end; + } + + int count() { + return ret; + } +}; + +/** + * Your CountIntervals object will be instantiated and called as such: + * CountIntervals* obj = new CountIntervals(); + * obj->add(left,right); + * int param_2 = obj->count(); + */ From 2d20c78e73496180c59ba316fc87e81f40fcc853 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:16:39 -0700 Subject: [PATCH 23/62] Update Readme.md --- Readme.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 40e48bbd0..d6d3eae3e 100644 --- a/Readme.md +++ b/Readme.md @@ -172,7 +172,6 @@ [480.Sliding-Window-Median](https://github.com/wisdompeak/LeetCode/blob/master/Heap/480.Sliding-Window-Median) (H) [218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H) [699.Falling-Squares](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/699.Falling-Squares) (H) -[715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) [729.My-Calendar-I](https://github.com/wisdompeak/LeetCode/tree/master/Heap/729.My-Calendar-I) (M) [855.Exam-Room](https://github.com/wisdompeak/LeetCode/tree/master/Heap/855.Exam-Room) (M+) [975.Odd-Even-Jump](https://github.com/wisdompeak/LeetCode/tree/master/Heap/975.Odd-Even-Jump) (H-) @@ -188,7 +187,10 @@ [1912.Design-Movie-Rental-System](https://github.com/wisdompeak/LeetCode/tree/master/Heap/1912.Design-Movie-Rental-System) (M+) 2034.Stock Price Fluctuation (M) [2071.Maximum-Number-of-Tasks-You-Can-Assign](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2071.Maximum-Number-of-Tasks-You-Can-Assign) (H) +```maintain intervals``` +[715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) [2213.Longest-Substring-of-One-Repeating-Character](https://github.com/wisdompeak/LeetCode/new/master/Heap/2213.Longest-Substring-of-One-Repeating-Character) (H) +[2276.Count-Integers-in-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Heap/2276.Count-Integers-in-Intervals) (H-) #### [Tree](https://github.com/wisdompeak/LeetCode/tree/master/Tree) [144.Binary-Tree-Preorder-Traversal](https://github.com/wisdompeak/LeetCode/tree/master/Tree/144.Binary-Tree-Preorder-Traversal) (M+) From 219555d4cab2caf4f3b48b10f7c0ad9dfb97a5fe Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:16:58 -0700 Subject: [PATCH 24/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index d6d3eae3e..5e1635559 100644 --- a/Readme.md +++ b/Readme.md @@ -187,7 +187,7 @@ [1912.Design-Movie-Rental-System](https://github.com/wisdompeak/LeetCode/tree/master/Heap/1912.Design-Movie-Rental-System) (M+) 2034.Stock Price Fluctuation (M) [2071.Maximum-Number-of-Tasks-You-Can-Assign](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2071.Maximum-Number-of-Tasks-You-Can-Assign) (H) -```maintain intervals``` +```maintain intervals``` [715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) [2213.Longest-Substring-of-One-Repeating-Character](https://github.com/wisdompeak/LeetCode/new/master/Heap/2213.Longest-Substring-of-One-Repeating-Character) (H) [2276.Count-Integers-in-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Heap/2276.Count-Integers-in-Intervals) (H-) From 677cff4cc6279b8ad3b1efd7b89d741e78ef34b7 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:17:33 -0700 Subject: [PATCH 25/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 5e1635559..812994031 100644 --- a/Readme.md +++ b/Readme.md @@ -187,7 +187,7 @@ [1912.Design-Movie-Rental-System](https://github.com/wisdompeak/LeetCode/tree/master/Heap/1912.Design-Movie-Rental-System) (M+) 2034.Stock Price Fluctuation (M) [2071.Maximum-Number-of-Tasks-You-Can-Assign](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2071.Maximum-Number-of-Tasks-You-Can-Assign) (H) -```maintain intervals``` + * ``maintain intervals`` [715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) [2213.Longest-Substring-of-One-Repeating-Character](https://github.com/wisdompeak/LeetCode/new/master/Heap/2213.Longest-Substring-of-One-Repeating-Character) (H) [2276.Count-Integers-in-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Heap/2276.Count-Integers-in-Intervals) (H-) From 0df9bde3e4758b39473ece30108adc878c647771 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:18:04 -0700 Subject: [PATCH 26/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 812994031..8d6344e5a 100644 --- a/Readme.md +++ b/Readme.md @@ -187,7 +187,7 @@ [1912.Design-Movie-Rental-System](https://github.com/wisdompeak/LeetCode/tree/master/Heap/1912.Design-Movie-Rental-System) (M+) 2034.Stock Price Fluctuation (M) [2071.Maximum-Number-of-Tasks-You-Can-Assign](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/2071.Maximum-Number-of-Tasks-You-Can-Assign) (H) - * ``maintain intervals`` +* ``Maintain intervals`` [715.Range-Module](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/715.Range-Module) (H) [2213.Longest-Substring-of-One-Repeating-Character](https://github.com/wisdompeak/LeetCode/new/master/Heap/2213.Longest-Substring-of-One-Repeating-Character) (H) [2276.Count-Integers-in-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Heap/2276.Count-Integers-in-Intervals) (H-) From 8c34a2bb7e6693c4e077296c96cece247008bfce Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 18:34:13 -0700 Subject: [PATCH 27/62] Create Readme.md --- .../Readme.md | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Heap/2276.Count-Integers-in-Intervals/Readme.md diff --git a/Heap/2276.Count-Integers-in-Intervals/Readme.md b/Heap/2276.Count-Integers-in-Intervals/Readme.md new file mode 100644 index 000000000..d41546d9c --- /dev/null +++ b/Heap/2276.Count-Integers-in-Intervals/Readme.md @@ -0,0 +1,41 @@ +### 2276.Count-Integers-in-Intervals + +此题的本质就是```715.Range-Module```. 我们常用map来维护互不重叠的区间,其中的key代表了区间的起点(并是有序排列),value表示区间的终点。 + +基本思想:我们维护一个计数器count表示当前有多少整数被记录。每当加入一个新区间,我们需要标记删除哪些旧区间(因为会与新区间重叠或相交),同时在count里减去这些旧区间对应的数字个数。然后加入新区间,同时在count里加上新区间的个数。注意新区间不一定就是[left,right],而是可能与旧区间merge后的大区间。 + +对于一个新区间[left,right],我们首先考虑left左边需要删除哪些旧区间。只有一种情况,就是如果left左边有一个区间与新区间重合的时候。如图 +``` + A B +_________ _____ _________ + __________________ + left right +``` +判定起来也很方便,用```iter = Map.lower_bound(left)```来定位区间B,然后prev(iter)就是区间A。如果A的右边界大于left,那么A区间就要被删除。此时,我们需要注意,之后加入的新区间因为要与A区间merge,它的起点将是```start = A->first```. + +对于一个新区间[left,right]右边需要删除的区间,则可能会有多个。如图 +``` + A B C D +_________ __ ___ _________ + __________________ + left right +``` +我们从B开始,一路向后遍历区间,直至发现D是最后一个左边界与right勾搭上的区间。于是区间B、C、D都会是需要待删除的区间。同理我们需要注意,之后加入的新区间因为要与BCD区间merge,它的终点将是```end = D->second```. 因此我们的代码长得如下: +```cpp +int end = right; +auto iter = Map.lower_bound(left); +while (iter!=Map.end() && iter->first <= end) +{ + end = max(end, iter->second); + iter = next(iter); +} +``` +但是这里有个疏漏,事实上A的右边界可以很靠后,所以初始值的end必须同样要考虑到A->second。所以要添加一行: +```cpp +int end = right; +auto iter = Map.lower_bound(left); +if (iter!=Map.begin()) + end = max(end, prev(iter)->second); +``` + +最终我们将这些标记要删除的区间都从Map里删除,并添加上新的```Map[start] = end```. From 3fa97d95e57f73d69d301651e5207ead54649958 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 22:51:18 -0700 Subject: [PATCH 28/62] Create 1893.Check-if-All-the-Integers-in-a-Range-Are-Covered.cpp --- ...ll-the-Integers-in-a-Range-Are-Covered.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered.cpp diff --git a/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered.cpp b/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered.cpp new file mode 100644 index 000000000..4cc423a71 --- /dev/null +++ b/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered.cpp @@ -0,0 +1,21 @@ +class Solution { +public: + bool isCovered(vector>& ranges, int left, int right) + { + vectordiff(52); + for (auto range:ranges) + { + diff[range[0]]+=1; + diff[range[1]+1]+=-1; + } + + int sum = 0; + for (int i=1; i<=50; i++) + { + sum += diff[i]; + if (i>=left && i<=right && sum==0) + return false; + } + return true; + } +}; From 5e1f37bdad918af22a952792a45e1b65f867eb6e Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 22:51:44 -0700 Subject: [PATCH 29/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 8d6344e5a..60b9f15e5 100644 --- a/Readme.md +++ b/Readme.md @@ -1232,7 +1232,7 @@ [1589.Maximum-Sum-Obtained-of-Any-Permutation](https://github.com/wisdompeak/LeetCode/tree/master/Others/1589.Maximum-Sum-Obtained-of-Any-Permutation) (M) [1674.Minimum-Moves-to-Make-Array-Complementary](https://github.com/wisdompeak/LeetCode/tree/master/Others/1674.Minimum-Moves-to-Make-Array-Complementary) (H) [1871.Jump-Game-VII](https://github.com/wisdompeak/LeetCode/tree/master/Others/1871.Jump-Game-VII) (M+) -1893.Check if All the Integers in a Range Are Covered (E) +[1893.Check-if-All-the-Integers-in-a-Range-Are-Covered](https://github.com/wisdompeak/LeetCode/tree/master/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered) (E) [1943.Describe-the-Painting](https://github.com/wisdompeak/LeetCode/tree/master/Others/1943.Describe-the-Painting) (H-) [2015.Average-Height-of-Buildings-in-Each-Segment](https://github.com/wisdompeak/LeetCode/tree/master/Others/2015.Average-Height-of-Buildings-in-Each-Segment) (H-) [2158.Amount-of-New-Area-Painted-Each-Day](https://github.com/wisdompeak/LeetCode/tree/master/Others/2158.Amount-of-New-Area-Painted-Each-Day) (H-) From 8619c6d0746cae1d8359d3e439dcf0a876605096 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月15日 22:56:07 -0700 Subject: [PATCH 30/62] Create Readme.md --- .../Readme.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/Readme.md diff --git a/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/Readme.md b/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/Readme.md new file mode 100644 index 000000000..c797b73f7 --- /dev/null +++ b/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered/Readme.md @@ -0,0 +1,5 @@ +### 1893.Check-if-All-the-Integers-in-a-Range-Are-Covered + +本题的数据范围非常小,每个数字的数值只在[1,50]之间,因为我们在数轴的[1,50]范围内用差分数组/扫描线来做。对于任何区间[a,b]的两个端点,我们标记差分信息:即在数轴上的a位置标记+1,在b+1位置标记-1,这样做积分的时候,就相当于只在区间[a,b]被抬升了1. + +最终我们只要考察积分曲线在[left,right]是否有任意一点的值为0.是的话返回false,否则返回true。 From dccf2d99296add4e36c15cdf4eaf92ad4c232b83 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月17日 22:49:08 -0700 Subject: [PATCH 31/62] Update Readme.md --- DFS/1192.Critical-Connections-in-a-Network/Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DFS/1192.Critical-Connections-in-a-Network/Readme.md b/DFS/1192.Critical-Connections-in-a-Network/Readme.md index 64537cb6b..94a2c7e37 100644 --- a/DFS/1192.Critical-Connections-in-a-Network/Readme.md +++ b/DFS/1192.Critical-Connections-in-a-Network/Readme.md @@ -6,11 +6,11 @@ 简单地说,我们可以以任意一个未访问过的节点作为根节点,用DFS的顺序来进行搜索,即永远深度优先,然后回溯再搜索其他分支。如果碰到访问过的节点,就停止,保证不行成环。 -我们在dfs的过程中维护两个数组,一个是dfs[u],表示节点u被第一次访问时的顺序(可以理解为时间戳),这个是唯一且不变的量。另一个数组low[u]比较关键,初始的时候```low[u]=dfn[u]```。我们以u为节点的开始dfs(注意抵达u之前可能还有u的父节点,但我们dfs的时候不走回头路),想象它最终形成一棵搜索树,那么u的所有子节点中止的条件不外乎有两个:一个是走进了死胡同;另一个就是遇到了已经访问过的节点,特别的,这个已经访问过的节点有可能是u的祖先节点!所以,有了这样的搜索树之后,low[u]可以有机会更新为它所有的子节点v可以接触到的最小时间戳low[v]。 +我们在dfs的过程中维护两个数组,一个是dfn[u],表示节点u被第一次访问时的顺序(可以理解为时间戳),这个是唯一且不变的量。另一个数组low[u]比较关键,初始的时候```low[u]=dfn[u]```。我们以u为节点的开始dfs(注意抵达u之前可能还有u的父节点,但我们dfs的时候不走回头路),想象它最终形成一棵搜索树,那么u的所有子节点中止的条件不外乎有两个:一个是走进了死胡同;另一个就是遇到了已经访问过的节点,特别的,这个已经访问过的节点有可能是u的祖先节点!所以,有了这样的搜索树之后,low[u]可以有机会更新为它所有的子节点v可以接触到的最小时间戳low[v]。 令v是u的一个子节点,且有```low[v]>dfn[u]```,这说明什么呢?说明从v出发最终无法绕道u的前面去。因此(v,u)就是割边。如果消除了这条边,v及其子树就是一个孤岛,无法与u或u的祖先相通。同理,如果```low[v]>=dfn[u]```,说明u是一个割点,如果消除了这个点,那么v及其子树也是一个孤岛。 本题中我们还设置了一个parent,其实是为了标记dfs过程中的搜索顺序。因为无向图```for auto v: next[u]```的遍历过程中,v可能是u的父节点,这种情况下v其实不能作为从u开始dfs的下一个目的地(否则就是走回头路了),所以得排除。 -[Leetcode Link](https://leetcode.com/problems/critical-connections-in-a-network) \ No newline at end of file +[Leetcode Link](https://leetcode.com/problems/critical-connections-in-a-network) From 0626bc0ca65035e707a31a90c7f6c24fcb0bdd57 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月17日 23:21:05 -0700 Subject: [PATCH 32/62] Update 351.Android-Unlock-Patterns.cpp --- .../351.Android-Unlock-Patterns.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DFS/351.Android-Unlock-Patterns/351.Android-Unlock-Patterns.cpp b/DFS/351.Android-Unlock-Patterns/351.Android-Unlock-Patterns.cpp index 040ab40e3..78a9af0d7 100644 --- a/DFS/351.Android-Unlock-Patterns/351.Android-Unlock-Patterns.cpp +++ b/DFS/351.Android-Unlock-Patterns/351.Android-Unlock-Patterns.cpp @@ -1,26 +1,26 @@ class Solution { int count = 0; int m,n; + int visited[3][3]; + vector>dir = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1},{-1,2},{1,2},{-2,1},{2,1},{-1,-2},{1,-2},{-2,-1},{2,-1}}; public: int numberOfPatterns(int m, int n) { this->m = m; this->n = n; - auto visited = vector>(3, vector(3,0)); - + for (int i=0; i<3; i++) for (int j=0; j<3; j++) { visited[i][j] = 1; - dfs(i,j,1,visited); + dfs(i,j,1); visited[i][j] = 0; } return count; } - void dfs(int x, int y, int r, vector>&visited) - { - auto dir = vector>({{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1},{-1,2},{1,2},{-2,1},{2,1},{-1,-2},{1,-2},{-2,-1},{2,-1}}); + void dfs(int x, int y, int r) + { if (r>=m && r<=n) count++; if (r>n) return; @@ -34,7 +34,7 @@ class Solution { if (visited[i][j] == 0) { visited[i][j] = 1; - dfs(i,j,r+1,visited); + dfs(i,j,r+1); visited[i][j] = 0; } else @@ -45,7 +45,7 @@ class Solution { continue; if (visited[i][j]==1) continue; visited[i][j] = 1; - dfs(i,j,r+1,visited); + dfs(i,j,r+1); visited[i][j] = 0; } } From 7b1f1524be03853f6da881a1e62da0c6352c4e38 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月18日 23:11:49 -0700 Subject: [PATCH 33/62] Update 2015.Average-Height-of-Buildings-in-Each-Segment.cpp --- ...ge-Height-of-Buildings-in-Each-Segment.cpp | 45 +++++++------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp index 28700cdd3..e88dadf1a 100644 --- a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp +++ b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp @@ -2,42 +2,27 @@ class Solution { public: vector> averageHeightOfBuildings(vector>& buildings) { - vector>p; + map>Map; // pos=>{sum, count} for (auto build: buildings) { int start = build[0], end = build[1], height = build[2]; - p.push_back({start, height}); - p.push_back({end, -height}); - } + Map[start].first += height; + Map[start].second += 1; + Map[end].first -= height; + Map[end].second -= 1; + } - sort(p.begin(), p.end()); - int count = 0; int sum = 0; - - vector>temp; - for (int i=0; i>temp; + for (auto& [pos, kv]: Map) { - int j = i; - while (j>rets; for (int i=0; i Date: 2022年5月18日 23:20:56 -0700 Subject: [PATCH 34/62] Update Readme.md --- .../Readme.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/Readme.md b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/Readme.md index 7bd96cafc..b576fd416 100644 --- a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/Readme.md +++ b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/Readme.md @@ -1,9 +1,7 @@ ### 2015.Average-Height-of-Buildings-in-Each-Segment -对于给出若干个区间、涉及到区间合并的问题,扫描线是比较自然的想法。 +本题显然是扫描线的解法。我们只关心那些建筑两边的边缘线位置。对于每处边界,要么增加一幢楼:楼的总高度和楼的总数量都会变大;要么减少一幢楼:楼的总高度和楼的总数量都会变小。所以本题在每处边界,需要考虑两个差分量:分别反映楼的总高度的变化heightDiff,和当前楼的数量的变化countDiff。 -我们只关注那些建筑两边的边缘线位置。将所有的边缘线按照位置从小到大排序之后,我们逐个遍历一遍。维护一个集合,遇到左边缘就插入h,遇到右边缘就删除h。于是,我们在每一个边缘线位置pos,都可以通过当前集合得到一个平均值avg,这意味着从pos往右直至下一个边缘线位置pos2,中间这部分区间[pos, pos2]就是一个输出恒为avg的线段。 +因为同一处位置可能是多幢楼的边界,我们先用map,将同一处位置的这两个差分量做累积。然后按照位置排序后,用积分走一遍得到当前的height和count,就可以得到每个区段的平均值。 -我们将这些琐碎的线段收集起来,合并输出相同的线段,并且剔除输出为0的线段,这剩余的这些线段就是答案。 - -另外,事实上我们不需要真正维护一个multiset。我们只关心集合的sum和count,因此用两个变量即可。 +最后记得要把相邻的、平均值相等的区间要合并。平均值为零的区间也要舍弃。 From cfdfb667a34e7aeaa9c121e92242ba43637c1cbb Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月19日 01:01:50 -0700 Subject: [PATCH 35/62] Update 2015.Average-Height-of-Buildings-in-Each-Segment.cpp --- ...ge-Height-of-Buildings-in-Each-Segment.cpp | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp index e88dadf1a..a0c551970 100644 --- a/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp +++ b/Others/2015.Average-Height-of-Buildings-in-Each-Segment/2015.Average-Height-of-Buildings-in-Each-Segment.cpp @@ -2,39 +2,38 @@ class Solution { public: vector> averageHeightOfBuildings(vector>& buildings) { - map>Map; // pos=>{sum, count} + map>Map; // pos -> {diffHeight, diffCount} for (auto build: buildings) { - int start = build[0], end = build[1], height = build[2]; - Map[start].first += height; - Map[start].second += 1; - Map[end].first -= height; - Map[end].second -= 1; - } + int s = build[0], e = build[1], h = build[2]; + Map[s].first += h; + Map[s].second += 1; + Map[e].first -= h; + Map[e].second -= 1; + } - int sum = 0; - int count = 0; - vector>temp; + vector>seg; + int totalHeight = 0, totalCount = 0; for (auto& [pos, kv]: Map) { - int heightDiff = kv.first, countDiff = kv.second; - sum += heightDiff; - count += countDiff; - int avg = (count==0 ? 0 : sum / count); - temp.push_back({pos, avg}); - } + int diffHeight = kv.first, diffCount = kv.second; + totalHeight += diffHeight; + totalCount += diffCount; + int avg = (totalCount ==0 ? 0: totalHeight / totalCount); + seg.push_back({pos, avg}); + } vector>rets; - for (int i=0; i Date: 2022年5月20日 05:04:09 -0700 Subject: [PATCH 36/62] Update 2158.Amount-of-New-Area-Painted-Each-Day.cpp --- ...58.Amount-of-New-Area-Painted-Each-Day.cpp | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/Others/2158.Amount-of-New-Area-Painted-Each-Day/2158.Amount-of-New-Area-Painted-Each-Day.cpp b/Others/2158.Amount-of-New-Area-Painted-Each-Day/2158.Amount-of-New-Area-Painted-Each-Day.cpp index 3190ac4a9..73922b6bf 100644 --- a/Others/2158.Amount-of-New-Area-Painted-Each-Day/2158.Amount-of-New-Area-Painted-Each-Day.cpp +++ b/Others/2158.Amount-of-New-Area-Painted-Each-Day/2158.Amount-of-New-Area-Painted-Each-Day.cpp @@ -1,36 +1,34 @@ -using AI3 = array; class Solution { public: vector amountPainted(vector>& paint) { - vectorarr; + map>>Map; // pos->{idx, flag} for (int i=0; i>>>array(Map.begin(), Map.end()); setSet; int n = paint.size(); - vectorrets(n); - for (int i=0; irets(n); + for (int i=0; i Date: 2022年5月20日 23:00:57 -0700 Subject: [PATCH 37/62] Update Readme.md --- Others/2158.Amount-of-New-Area-Painted-Each-Day/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Others/2158.Amount-of-New-Area-Painted-Each-Day/Readme.md b/Others/2158.Amount-of-New-Area-Painted-Each-Day/Readme.md index 69b400739..ccdb904be 100644 --- a/Others/2158.Amount-of-New-Area-Painted-Each-Day/Readme.md +++ b/Others/2158.Amount-of-New-Area-Painted-Each-Day/Readme.md @@ -1,6 +1,6 @@ ### 2158.Amount-of-New-Area-Painted-Each-Day -此题是扫描线一例非常特别的应用。 +此题其实类似于```218. The Skyline Problem```的扫描线解法。 通常的扫描线算法跟踪的是每个分割区间的重叠数目(比如说这一段区间有三条线段重叠,下一个区间有两条线段重叠),但本题跟踪的是每个区间的重叠信息。我们可以用于扫描线一样的算法,用一个有序集合来跟踪在每个分割区间内,有哪些线段在此重叠:如果是线段开头就加入,如果是线段结尾就删除。显然,编号最小的线段最先拥有这个区间的打印权,故把这段分割区间的长度记在这条线段上即可。 From 3a30051745f4bd76b27511bab08c4e0997dfc433 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月20日 23:33:14 -0700 Subject: [PATCH 38/62] Create 930.Binary-Subarrays-With-Sum_v2.cpp --- .../930.Binary-Subarrays-With-Sum_v2.cpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Hash/930.Binary-Subarrays-With-Sum/930.Binary-Subarrays-With-Sum_v2.cpp diff --git a/Hash/930.Binary-Subarrays-With-Sum/930.Binary-Subarrays-With-Sum_v2.cpp b/Hash/930.Binary-Subarrays-With-Sum/930.Binary-Subarrays-With-Sum_v2.cpp new file mode 100644 index 000000000..78bd1e41c --- /dev/null +++ b/Hash/930.Binary-Subarrays-With-Sum/930.Binary-Subarrays-With-Sum_v2.cpp @@ -0,0 +1,34 @@ +class Solution { +public: + int numSubarraysWithSum(vector& A, int S) + { + int n = A.size(); + vectorpostZeros(n); + int count = 0; + for (int i=n-1; i>=0; i--) + { + postZeros[i] = count; + if (A[i]==0) + count++; + else + count = 0; + } + + int j = 0, sum = 0; + int ret = 0; + for (int i=0; i Date: 2022年5月20日 23:33:44 -0700 Subject: [PATCH 39/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 60b9f15e5..a3dbab027 100644 --- a/Readme.md +++ b/Readme.md @@ -34,6 +34,7 @@ * ``Sliding window`` [532.K-diff-Pairs-in-an-Array](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/532.K-diff-Pairs-in-an-Array) (H-) [611.Valid-Triangle-Number](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/611.Valid-Triangle-Number) (M+) +[930.Binary-Subarrays-With-Sum](https://github.com/wisdompeak/LeetCode/tree/master/Hash/930.Binary-Subarrays-With-Sum) (M+) [1004.Max-Consecutive-Ones-III](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1004.Max-Consecutive-Ones-III) (M) [1052.Grumpy-Bookstore-Owner](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1052.Grumpy-Bookstore-Owner) (M) [1838.Frequency-of-the-Most-Frequent-Element](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1838.Frequency-of-the-Most-Frequent-Element) (H-) From 74d918afd8d3d7f4ef9646ee7be7358c4ac0f575 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月20日 23:51:21 -0700 Subject: [PATCH 40/62] Update Readme.md --- Hash/930.Binary-Subarrays-With-Sum/Readme.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Hash/930.Binary-Subarrays-With-Sum/Readme.md b/Hash/930.Binary-Subarrays-With-Sum/Readme.md index 2040be321..0196f2370 100644 --- a/Hash/930.Binary-Subarrays-With-Sum/Readme.md +++ b/Hash/930.Binary-Subarrays-With-Sum/Readme.md @@ -1,6 +1,6 @@ ### 930.Binary-Subarrays-With-Sum -此题是考察对Hash+prefix的常见组合。 +#### 解法1:Hash+prefix 我们遍历每一个元素j,考察以j为结尾、满足条件的subarray,这样的起点i可以在哪里?如果满足条件的起点i有多种可能,那么答案就可以累加上这么多数量. @@ -9,4 +9,11 @@ ret += Map[prefix[j] - S] ``` +#### 解法2:Sliding Window +遍历左边界左边界。假设左边界为i,那么可以向右单调移动j直至滑窗内的元素和恰好为S。此时如果知道j右边有k个连续的0,那么就意味着以i为左边界、元素和是S的滑窗就有k+1个。 + +对于每个元素,它后面有多少个连续的0,可以提前预处理得到的。 + +因为i和j都是单调移动的,所以时间复杂度是o(N). + [Leetcode Link](https://leetcode.com/problems/binary-subarrays-with-sum) From 416f6d1e559c9aafd5b3d4db9c6ba85c3c39c859 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 00:40:40 -0700 Subject: [PATCH 41/62] Update 218.The-Skyline-Problem.cpp --- .../218.The-Skyline-Problem.cpp | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem.cpp b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem.cpp index 5c774b5a9..f62cd9504 100644 --- a/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem.cpp +++ b/Segment_Tree/218.The-Skyline-Problem/218.The-Skyline-Problem.cpp @@ -1,33 +1,31 @@ class Solution { public: - vector> getSkyline(vector>& buildings) + vector> getSkyline(vector>& buildings) { - vector>edges; - for (int i=0;i>>Map; // pos->{height, flag} + for (auto building: buildings) { - edges.push_back({buildings[i][0],-buildings[i][2]}); - edges.push_back({buildings[i][1],buildings[i][2]}); + Map[building[0]].push_back({building[2], 1}); + Map[building[1]].push_back({building[2], -1}); } - sort(edges.begin(),edges.end()); - - multisetSet={0}; - vector>results; - int cur=0; - - for (int i=0; iSet; + vector>rets; + for (auto& [pos, pairs]: Map) { - if (edges[i][1]<0) - Set.insert(-edges[i][1]); - else - Set.erase(Set.lower_bound(edges[i][1])); - - int H=*Set.rbegin(); - if (cur!=H) - results.push_back({edges[i][0],H}); - cur=H; + for (auto& [height, flag]: pairs) + { + if (flag == 1) + Set.insert(height); + else + Set.erase(Set.find(height)); + } + + int H = Set.empty() ? 0: *Set.rbegin(); + if (rets.empty() || rets.back()[1]!=H) + rets.push_back({pos, H}); } - - return results; + + return rets; } }; From 05186512d124e7e7ede0412f3cca2ae81e51ff39 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 00:41:29 -0700 Subject: [PATCH 42/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index a3dbab027..2b1a2f499 100644 --- a/Readme.md +++ b/Readme.md @@ -171,7 +171,6 @@ [363.Max-Sum-of-Rectangle-No-Larger-Than-K](https://github.com/wisdompeak/LeetCode/tree/master/Heap/363.Max-Sum-of-Rectangle-No-Larger-Than-K) (H) [352.Data-Stream-as-Disjoint-Intervals](https://github.com/wisdompeak/LeetCode/tree/master/Heap/352.Data-Stream-as-Disjoint-Intervals) (H) [480.Sliding-Window-Median](https://github.com/wisdompeak/LeetCode/blob/master/Heap/480.Sliding-Window-Median) (H) -[218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H) [699.Falling-Squares](https://github.com/wisdompeak/LeetCode/tree/master/Segment_Tree/699.Falling-Squares) (H) [729.My-Calendar-I](https://github.com/wisdompeak/LeetCode/tree/master/Heap/729.My-Calendar-I) (M) [855.Exam-Room](https://github.com/wisdompeak/LeetCode/tree/master/Heap/855.Exam-Room) (M+) @@ -1236,6 +1235,7 @@ [1893.Check-if-All-the-Integers-in-a-Range-Are-Covered](https://github.com/wisdompeak/LeetCode/tree/master/Others/1893.Check-if-All-the-Integers-in-a-Range-Are-Covered) (E) [1943.Describe-the-Painting](https://github.com/wisdompeak/LeetCode/tree/master/Others/1943.Describe-the-Painting) (H-) [2015.Average-Height-of-Buildings-in-Each-Segment](https://github.com/wisdompeak/LeetCode/tree/master/Others/2015.Average-Height-of-Buildings-in-Each-Segment) (H-) +[218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H) [2158.Amount-of-New-Area-Painted-Each-Day](https://github.com/wisdompeak/LeetCode/tree/master/Others/2158.Amount-of-New-Area-Painted-Each-Day) (H-) 2237.Count-Positions-on-Street-With-Required-Brightness (M) [2251.Number-of-Flowers-in-Full-Bloom](https://github.com/wisdompeak/LeetCode/tree/master/Others/2251.Number-of-Flowers-in-Full-Bloom) (M) From bb6a000efd5fb0a069d5ee0d145a46a6bdd19c7b Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 00:47:36 -0700 Subject: [PATCH 43/62] Update Readme.md --- Segment_Tree/218.The-Skyline-Problem/Readme.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Segment_Tree/218.The-Skyline-Problem/Readme.md b/Segment_Tree/218.The-Skyline-Problem/Readme.md index 549e31dac..5787ea49c 100644 --- a/Segment_Tree/218.The-Skyline-Problem/Readme.md +++ b/Segment_Tree/218.The-Skyline-Problem/Readme.md @@ -1,16 +1,12 @@ ### 218.The-Skyline-Problem -#### 解法1:有序容器 +#### 解法1:扫描线 -此题需要设置一个multiSet记录所有的当前下降沿的高度,则*prev(Set.end(),1)就是这个Set里的最大值。 +我们维护一个multiset,按照横轴的位置顺次考虑各个楼的上升沿和下降沿。遇到上升沿就往集合里加入一个H,遇到下降沿就在集合里删除一个H。这样每个时刻,集合里面的最大值,就代表了该位置(及其右边区间)的天际线高度。我们将这些```{位置,高度}```记录下来,就代表了天际线的轮廓。 -首先,将所有的edges放入一个数组,按时间顺序排序,然后顺次遍历考虑:如果是上升沿,则在Set里加入对应高度(即添加一个上升沿);如果是下降沿,则需要在Set里删除对应的高度(即退出当前的下降沿)。 +注意,如果相邻两个位置的高度一样,那么我们可以只保留第一个。 -那何时对results进行更新呢?我们在每次处理edge时,不管是加入上升边沿还是退出下降沿之后,都意味着天际线有可能变动。天际线会变成什么呢?答案是此时Set里的最大值!回想一下,Set里装的是所有当前仍未退出的下降沿,说明他们都在当前可以撑起对应的高度。那么Set里的最大值就是当前天际线的最高值。 - -所以每次查看一个edges,我们都要比较当前的高度(用cur记录)和Set里的最大值进行比较:一旦不同,就用Set里的最大值去加入results,同时也要更新cur。 - -有一个细节需要注意,在生成edges数组时,如果某一个位置同时有上升沿也有下降沿,注意要先考察上升沿,再考察下降沿。也就是要先加入一个上升沿,再退出可能的下降沿。否则类似[[0,2,3],[2,5,3]]的测试例子就会有问题。 +类似的题目有```2158.Amount-of-New-Area-Painted-Each-Day```. #### 解法2:线段树 From 322c53ce0ce5aa4a82c33d8317d707d0105960b7 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 17:07:31 -0700 Subject: [PATCH 44/62] Create 2237.Count-Positions-on-Street-With-Required-Brightness.cpp --- ...ons-on-Street-With-Required-Brightness.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Others/2237.Count-Positions-on-Street-With-Required-Brightness/2237.Count-Positions-on-Street-With-Required-Brightness.cpp diff --git a/Others/2237.Count-Positions-on-Street-With-Required-Brightness/2237.Count-Positions-on-Street-With-Required-Brightness.cpp b/Others/2237.Count-Positions-on-Street-With-Required-Brightness/2237.Count-Positions-on-Street-With-Required-Brightness.cpp new file mode 100644 index 000000000..ec7423263 --- /dev/null +++ b/Others/2237.Count-Positions-on-Street-With-Required-Brightness/2237.Count-Positions-on-Street-With-Required-Brightness.cpp @@ -0,0 +1,31 @@ +class Solution { +public: + int meetRequirement(int n, vector>& lights, vector& requirement) + { + vectordiff(n+1); + for (int i=0; ibright(n); + int sum = 0; + for (int i=0; i=requirement[i]) + ret++; + } + return ret; + } +}; From 98a3d37e24439956a449ca4b4e5511cb24cc5e4a Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 17:07:55 -0700 Subject: [PATCH 45/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 2b1a2f499..06a354a15 100644 --- a/Readme.md +++ b/Readme.md @@ -1237,7 +1237,7 @@ [2015.Average-Height-of-Buildings-in-Each-Segment](https://github.com/wisdompeak/LeetCode/tree/master/Others/2015.Average-Height-of-Buildings-in-Each-Segment) (H-) [218.The-Skyline-Problem](https://github.com/wisdompeak/LeetCode/blob/master/Segment_Tree/218.The-Skyline-Problem) (H) [2158.Amount-of-New-Area-Painted-Each-Day](https://github.com/wisdompeak/LeetCode/tree/master/Others/2158.Amount-of-New-Area-Painted-Each-Day) (H-) -2237.Count-Positions-on-Street-With-Required-Brightness (M) +[2237.Count-Positions-on-Street-With-Required-Brightness](https://github.com/wisdompeak/LeetCode/tree/master/Others/2237.Count-Positions-on-Street-With-Required-Brightness) (M) [2251.Number-of-Flowers-in-Full-Bloom](https://github.com/wisdompeak/LeetCode/tree/master/Others/2251.Number-of-Flowers-in-Full-Bloom) (M) * ``二维差分`` [850.Rectangle-Area-II](https://github.com/wisdompeak/LeetCode/tree/master/Others/850.Rectangle-Area-II) (H) From 280e09c9fe2fdf92c163429c3fe68b28c8b6770e Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 17:11:59 -0700 Subject: [PATCH 46/62] Create Readme.md --- .../Readme.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Others/2237.Count-Positions-on-Street-With-Required-Brightness/Readme.md diff --git a/Others/2237.Count-Positions-on-Street-With-Required-Brightness/Readme.md b/Others/2237.Count-Positions-on-Street-With-Required-Brightness/Readme.md new file mode 100644 index 000000000..456084618 --- /dev/null +++ b/Others/2237.Count-Positions-on-Street-With-Required-Brightness/Readme.md @@ -0,0 +1,3 @@ +### 2237.Count-Positions-on-Street-With-Required-Brightness + +扫描线算法的模板题。假设某盏灯的覆盖范围是[a,b],那么我们就设置差分数组diff[a]+=1和diff[b+1]-=1. 注意因为在b位置处我们是希望计入被灯光覆盖,所以-1的差分应该写在b+1这个地方。 From 240128f687414e76d8f873c2c079eb04fff4881a Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 17:40:44 -0700 Subject: [PATCH 47/62] Create 490.The-Maze.cpp --- BFS/490.The-Maze/490.The-Maze.cpp | 49 +++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 BFS/490.The-Maze/490.The-Maze.cpp diff --git a/BFS/490.The-Maze/490.The-Maze.cpp b/BFS/490.The-Maze/490.The-Maze.cpp new file mode 100644 index 000000000..accdb5d23 --- /dev/null +++ b/BFS/490.The-Maze/490.The-Maze.cpp @@ -0,0 +1,49 @@ +class Solution { + int M,N; + vector> dir = {{1,0},{-1,0},{0,1},{0,-1}}; + +public: + bool hasPath(vector>& maze, vector& start, vector& destination) + { + if (start==destination) return true; + + M = maze.size(); + N = maze[0].size(); + + auto visited=vector>(M,vector(N,0)); + + queue>q; + q.push({start[0],start[1]}); + visited[start[0]][start[1]] = 1; + + while (!q.empty()) + { + int x0 = q.front().first; + int y0 = q.front().second; + q.pop(); + + for (int k=0; k<4; k++) + { + auto [x,y] = nextPos(maze,x0,y0,k); + if (x==destination[0] && y==destination[1]) return true; + if (visited[x][y]==1) continue; + visited[x][y]=1; + q.push({x,y}); + } + } + return false; + } + + pair nextPos(vector>& maze, int x0, int y0, int k) + { + int x = x0, y = y0; + while (x>=0 && x=0 && y Date: 2022年5月21日 17:42:14 -0700 Subject: [PATCH 48/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 06a354a15..f752629cd 100644 --- a/Readme.md +++ b/Readme.md @@ -461,6 +461,7 @@ [126.Word-Ladder-II](https://github.com/wisdompeak/LeetCode/tree/master/BFS/126.Word-Ladder-II) (M+) [130.Surrounded-Regions](https://github.com/wisdompeak/LeetCode/tree/master/Union_Find/130.Surrounded-Regions) (H-) [200.Number-of-Islands](https://github.com/wisdompeak/LeetCode/tree/master/DFS/200.Number-of-Islands) (H-) +[490.The-Maze](https://github.com/wisdompeak/LeetCode/tree/master/BFS/490.The-Maze) (M) [529.Minesweeper](https://github.com/wisdompeak/LeetCode/tree/master/BFS/529.Minesweeper) (M+) [637.Average-of-Levels-in-Binary-Tree](https://github.com/wisdompeak/LeetCode/tree/master/BFS/637.Average-of-Levels-in-Binary-Tree) (M) [675.Cut-Off-Trees-for-Golf-Event](https://github.com/wisdompeak/LeetCode/tree/master/BFS/675.Cut-Off-Trees-for-Golf-Event) (M) From 1af2dae394e2723b1f368c30e6ba2867e21934f2 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月21日 17:45:40 -0700 Subject: [PATCH 49/62] Create Readme.md --- BFS/490.The-Maze/Readme.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 BFS/490.The-Maze/Readme.md diff --git a/BFS/490.The-Maze/Readme.md b/BFS/490.The-Maze/Readme.md new file mode 100644 index 000000000..c0abff1da --- /dev/null +++ b/BFS/490.The-Maze/Readme.md @@ -0,0 +1,3 @@ +### 490.The-Maze + +常规的BFS。只不过以往是"每个回合朝一个方向走一步",现在是"每个回合朝一个方向走到底"。 From fef2ba8f432a4baf2f4b38f219edb03b43e42a99 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 09:04:16 -0700 Subject: [PATCH 50/62] Create 6077.Sum-of-Total-Strength-of-Wizards.cpp --- .../6077.Sum-of-Total-Strength-of-Wizards.cpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp b/Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp new file mode 100644 index 000000000..50efb8071 --- /dev/null +++ b/Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp @@ -0,0 +1,49 @@ +using LL = long long; +LL M = 1e9+7; +class Solution { +public: + int totalStrength(vector& nums) + { + int n = nums.size(); + nums.insert(nums.begin(), 0); + + vectorpresum(n+2, 0); + for (int i=1; i<=n; i++) + presum[i] = (presum[i-1]+(LL)nums[i]) % M; + + vectorpresum1(n+2, 0); + for (int i=1; i<=n; i++) + presum1[i] = (presum1[i-1]+(LL)nums[i]*i) % M; + + stackStack; + vectornextSmaller(n+2,n+1); + vectorprevSmaller(n+2,0); + for (int i=1; i<=n; i++) + { + while (!Stack.empty() && nums[Stack.top()]>nums[i]) + { + nextSmaller[Stack.top()] = i; + Stack.pop(); + } + if (!Stack.empty()) + prevSmaller[i] = Stack.top(); + Stack.push(i); + } + + LL ret = 0; + for (int i=1; i<=n; i++) + { + LL a = prevSmaller[i], b = nextSmaller[i]; + LL x = i-a, y = b-i; + LL first = ((presum1[i-1] - presum1[a]) - (presum[i-1] - presum[a]) * a %M + M) % M; + first = first * y % M; + LL second = ((presum[b-1] - presum[i]) * (b-1+1) - (presum1[b-1] - presum1[i]) + M ) % M; + second = second * x % M; + LL mid = (LL)nums[i] * x * y % M; + + ret = (ret +(first + second + mid) * nums[i]) % M; + } + + return ret; + } +}; From afcbc2649636256868b734018316eebe13cd2861 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 09:05:14 -0700 Subject: [PATCH 51/62] Update Readme.md --- Readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Readme.md b/Readme.md index f752629cd..43847c8c4 100644 --- a/Readme.md +++ b/Readme.md @@ -1219,6 +1219,7 @@ [1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition) (H-) [2104.Sum-of-Subarray-Ranges](https://github.com/wisdompeak/LeetCode/tree/master/Stack/2104.Sum-of-Subarray-Ranges) (H-) [2262.Total-Appeal-of-A-String](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2262.Total-Appeal-of-A-String) (M+) +[6077.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/6077.Sum-of-Total-Strength-of-Wizards) (H) * ``扫描线 / 差分数组`` [252.Meeting-Rooms](https://github.com/wisdompeak/LeetCode/tree/master/Others/252.Meeting-Rooms) (M) [253.Meeting-Rooms-II](https://github.com/wisdompeak/LeetCode/tree/master/Others/253.Meeting-Rooms-II) (M+) @@ -1257,6 +1258,7 @@ [1878.Get-Biggest-Three-Rhombus-Sums-in-a-Grid](https://github.com/wisdompeak/LeetCode/tree/master/Others/1878.Get-Biggest-Three-Rhombus-Sums-in-a-Grid) (M+) [1906.Minimum-Absolute-Difference-Queries](https://github.com/wisdompeak/LeetCode/tree/master/Others/1906.Minimum-Absolute-Difference-Queries) (M+) [2245.Maximum-Trailing-Zeros-in-a-Cornered-Path](https://github.com/wisdompeak/LeetCode/tree/master/Others/2245.Maximum-Trailing-Zeros-in-a-Cornered-Path) (M) +[6077.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/6077.Sum-of-Total-Strength-of-Wizards) (H) * ``2D Presum`` 1314.Matrix-Block-Sum (M) [1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold) (H-) From d7b3e14ccd2151eb8771cbcdab2ed4a6a3fb6d2b Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 18:40:51 -0700 Subject: [PATCH 52/62] Create Readme.md --- .../Readme.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md new file mode 100644 index 000000000..b03e4a09b --- /dev/null +++ b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md @@ -0,0 +1,25 @@ +### 6077.Sum-of-Total-Strength-of-Wizards + +根据套路,我们不会去枚举所有的subarray再找其中的weakest。相反,我们遍历每个元素将其作为weakest,再找对应的subarray。 + +假设位置在i的元素nums[i],其prevSmaller在位置a,nextSmaller在位置b。那么以nums[i]为weakest的subarray,左边界可以在a与i之间任意间隙,记做有```x = i-a```种可能;右边界可以再i与b之间的任意间隙,记做有```y = b-i```种可能。 +``` +a X X X X i X X X b +``` +也就是说,共有xy种subarray符合条件。我们需要累加所有这些subarray元素和。然后再乘以nums[i]本身,加入最终答案。 + +那么"累加所有这些subarray元素和"呢?对于上面的例子,无论subarray的右边界在哪里,nums[a+1]只会当左边界在a/a+1之间时被计入,即被统计了一次。同理,nums[a+2]会在左边界位于a/a+1之间,a+1/a+2之间时被计入,即被统计了两次。依次类推,i左边的四个元素被计入的次数是: +``` +a X X X X i X X X b + 1 2 3 4 +``` +所以他们对"累加所有这些subarray元素和"的贡献就是:```M = S * y```,其中``` S = nums[a+1]*1 + nums[a+2]*2 + nums[a+3]*3 + nums[a+4]*4 ...``` 乘以y是因为无论subarray的右边界在哪个位置,nums[i]左边的这些元素都会以一样的频次被计入subarray。 + +接下来考虑如何计算S。不难构造以index为系数的前缀和```presum2[i] = sum{nums[k]*k} for k=0,1,2,..i```,那么就有```presum2[i-1]-presum2[a] = nums[a+1]*(a+1) + nums[a+2]*(a+2) + nums[a+3]*(a+3) + nums[a+4]*(a+4) ...```。显然只要将其再减去常规的区间```sum[a+1:i]*a```,就是S了。综上即有```S = presum2[i-1]-presum2[a] - (presum[i-1] - presum[a]) * a```. + +类似地,我们希望处理右边的情况,我们同样标记i右边的是三个元素被计入的次数: +``` +a X X X X i X X X b + 3 2 1 +``` +同理,这里我们希望计算``` S = nums[i+1]*3 + nums[i+2]*2 + nums[i+3]*...```。 From cf23f972766a445e8e6de88b1d7768629589f45d Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 21:52:30 -0700 Subject: [PATCH 53/62] Update Readme.md --- .../Readme.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md index b03e4a09b..1c39a9b3b 100644 --- a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md +++ b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md @@ -2,24 +2,30 @@ 根据套路,我们不会去枚举所有的subarray再找其中的weakest。相反,我们遍历每个元素将其作为weakest,再找对应的subarray。 -假设位置在i的元素nums[i],其prevSmaller在位置a,nextSmaller在位置b。那么以nums[i]为weakest的subarray,左边界可以在a与i之间任意间隙,记做有```x = i-a```种可能;右边界可以再i与b之间的任意间隙,记做有```y = b-i```种可能。 +假设位置在i的元素nums[i],其prevSmaller在位置a,nextSmaller在位置b。那么以nums[i]为weakest的subarray,左边界可以在a与i之间任意间隙,记做有```x = i-a```种可能;右边界可以在i与b之间的任意间隙,记做有```y = b-i```种可能。 ``` a X X X X i X X X b ``` -也就是说,共有xy种subarray符合条件。我们需要累加所有这些subarray元素和。然后再乘以nums[i]本身,加入最终答案。 +也就是说,共有```x*y```种subarray符合条件。我们需要累加所有这些subarray的元素和。然后再乘以nums[i]本身,加入最终答案。 -那么"累加所有这些subarray元素和"呢?对于上面的例子,无论subarray的右边界在哪里,nums[a+1]只会当左边界在a/a+1之间时被计入,即被统计了一次。同理,nums[a+2]会在左边界位于a/a+1之间,a+1/a+2之间时被计入,即被统计了两次。依次类推,i左边的四个元素被计入的次数是: +那么"累加所有这些subarray元素和"呢?对于上面的例子,无论subarray的右边界在哪里,nums[a+1]只会当左边界在a/a+1之间时被计入,即被统计了一次。同理,nums[a+2]会当左边界在位于a/a+1之间,或者a+1/a+2之间时被计入,即被统计了两次。依次类推,i左边的四个元素被计入的次数是: ``` a X X X X i X X X b 1 2 3 4 ``` -所以他们对"累加所有这些subarray元素和"的贡献就是:```M = S * y```,其中``` S = nums[a+1]*1 + nums[a+2]*2 + nums[a+3]*3 + nums[a+4]*4 ...``` 乘以y是因为无论subarray的右边界在哪个位置,nums[i]左边的这些元素都会以一样的频次被计入subarray。 +所以他们对"累加所有这些subarray元素和"的贡献就是:```M = S * y```,其中``` S = nums[a+1]*1 + nums[a+2]*2 + nums[a+3]*3 + nums[a+4]*4 ...``` 乘以y是因为无论subarray的右边界在哪个位置,nums[i]左边的这些元素都会以一样的频次被计入subarray,所以要重复y次。 -接下来考虑如何计算S。不难构造以index为系数的前缀和```presum2[i] = sum{nums[k]*k} for k=0,1,2,..i```,那么就有```presum2[i-1]-presum2[a] = nums[a+1]*(a+1) + nums[a+2]*(a+2) + nums[a+3]*(a+3) + nums[a+4]*(a+4) ...```。显然只要将其再减去常规的区间```sum[a+1:i]*a```,就是S了。综上即有```S = presum2[i-1]-presum2[a] - (presum[i-1] - presum[a]) * a```. +接下来考虑如何计算S。不难构造以index为权重的前缀和```presum2[i] = sum{nums[k]*k} for k=0,1,2,..i```,那么就有```presum2[i-1]-presum2[a] = nums[a+1]*(a+1) + nums[a+2]*(a+2) + nums[a+3]*(a+3) + nums[a+4]*(a+4) ...```。显然只要将其再减去常规的区间```sum[a+1:i]*a```,就是S了。综上即有```S = presum2[i-1]-presum2[a] - (presum[i-1] - presum[a]) * a```. 类似地,我们希望处理右边的情况,我们同样标记i右边的是三个元素被计入的次数: ``` a X X X X i X X X b 3 2 1 ``` -同理,这里我们希望计算``` S = nums[i+1]*3 + nums[i+2]*2 + nums[i+3]*...```。 +同理,这里我们希望计算``` S = nums[i+1]*3 + nums[i+2]*2 + nums[i+3]*...```。我们同样可以利用presum和presum2,具体的是```S = (presum[b-1]-presum[i])*(b+1) - (presum2[b-1]-presum2[i])```. 于是nums[i]右边的三个元素对于"累加所有这些subarray元素和"的贡献就是```S*x```. + +此外,别忘了nums[i]本身对于"累加所有这些subarray元素和"的贡献是```nums[i]*x*y```. + +所以以上三部分相加,再乘以nums[i]本身,就是以nums[i]为weakest的subarray的total strength. + +本题还有一个注意点,就是如果subarray里面如果有多个位置出现了最小值,那么哪个算weakest?为了避免重复,我们可以约定最左边出现的最小值算该subarray的weakest。所以本题中我们在预处理时,实际需要求的是prevSmallerOrEqual和nextSmaller。类似的题目见```2104.Sum-of-Subarray-Ranges```. From 668082c251415f792064ce7fe198581492721f40 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 22:04:38 -0700 Subject: [PATCH 54/62] Update Readme.md --- Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md index 1c39a9b3b..79a422d31 100644 --- a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md +++ b/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md @@ -22,7 +22,7 @@ a X X X X i X X X b a X X X X i X X X b 3 2 1 ``` -同理,这里我们希望计算``` S = nums[i+1]*3 + nums[i+2]*2 + nums[i+3]*...```。我们同样可以利用presum和presum2,具体的是```S = (presum[b-1]-presum[i])*(b+1) - (presum2[b-1]-presum2[i])```. 于是nums[i]右边的三个元素对于"累加所有这些subarray元素和"的贡献就是```S*x```. +同理,这里我们希望计算``` S = nums[i+1]*3 + nums[i+2]*2 + nums[i+3]*...```。我们同样可以利用presum和presum2,具体的是```S = (presum[b-1]-presum[i])*b - (presum2[b-1]-presum2[i])```. 于是nums[i]右边的三个元素对于"累加所有这些subarray元素和"的贡献就是```S*x```. 此外,别忘了nums[i]本身对于"累加所有这些subarray元素和"的贡献是```nums[i]*x*y```. From c84c8d26ec23c27125d34cb2e82551161ebbc7b4 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 22:05:56 -0700 Subject: [PATCH 55/62] Update and rename Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp to Others/2281.Sum-of-Total-Strength-of-Wizards/2281.Sum-of-Total-Strength-of-Wizards.cpp --- .../2281.Sum-of-Total-Strength-of-Wizards.cpp} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename Others/{6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp => 2281.Sum-of-Total-Strength-of-Wizards/2281.Sum-of-Total-Strength-of-Wizards.cpp} (86%) diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp b/Others/2281.Sum-of-Total-Strength-of-Wizards/2281.Sum-of-Total-Strength-of-Wizards.cpp similarity index 86% rename from Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp rename to Others/2281.Sum-of-Total-Strength-of-Wizards/2281.Sum-of-Total-Strength-of-Wizards.cpp index 50efb8071..d44005662 100644 --- a/Others/6077.Sum-of-Total-Strength-of-Wizards/6077.Sum-of-Total-Strength-of-Wizards.cpp +++ b/Others/2281.Sum-of-Total-Strength-of-Wizards/2281.Sum-of-Total-Strength-of-Wizards.cpp @@ -11,9 +11,9 @@ class Solution { for (int i=1; i<=n; i++) presum[i] = (presum[i-1]+(LL)nums[i]) % M; - vectorpresum1(n+2, 0); + vectorpresum2(n+2, 0); for (int i=1; i<=n; i++) - presum1[i] = (presum1[i-1]+(LL)nums[i]*i) % M; + presum2[i] = (presum2[i-1]+(LL)nums[i]*i) % M; stackStack; vectornextSmaller(n+2,n+1); @@ -35,9 +35,9 @@ class Solution { { LL a = prevSmaller[i], b = nextSmaller[i]; LL x = i-a, y = b-i; - LL first = ((presum1[i-1] - presum1[a]) - (presum[i-1] - presum[a]) * a %M + M) % M; + LL first = ((presum2[i-1] - presum2[a]) - (presum[i-1] - presum[a]) * a %M + M) % M; first = first * y % M; - LL second = ((presum[b-1] - presum[i]) * (b-1+1) - (presum1[b-1] - presum1[i]) + M ) % M; + LL second = ((presum[b-1] - presum[i]) * (b-1+1) - (presum2[b-1] - presum2[i]) + M ) % M; second = second * x % M; LL mid = (LL)nums[i] * x * y % M; From 89d0265546a487879e9ea4bb8f60c2d1af954210 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 22:06:23 -0700 Subject: [PATCH 56/62] Rename Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md to Others/2281.Sum-of-Total-Strength-of-Wizards/Readme.md --- .../Readme.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Others/{6077.Sum-of-Total-Strength-of-Wizards => 2281.Sum-of-Total-Strength-of-Wizards}/Readme.md (100%) diff --git a/Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md b/Others/2281.Sum-of-Total-Strength-of-Wizards/Readme.md similarity index 100% rename from Others/6077.Sum-of-Total-Strength-of-Wizards/Readme.md rename to Others/2281.Sum-of-Total-Strength-of-Wizards/Readme.md From 78d4974ddcb408341c930164bed7e993732cb478 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 22:16:50 -0700 Subject: [PATCH 57/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 43847c8c4..127b68195 100644 --- a/Readme.md +++ b/Readme.md @@ -1219,7 +1219,7 @@ [1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition) (H-) [2104.Sum-of-Subarray-Ranges](https://github.com/wisdompeak/LeetCode/tree/master/Stack/2104.Sum-of-Subarray-Ranges) (H-) [2262.Total-Appeal-of-A-String](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2262.Total-Appeal-of-A-String) (M+) -[6077.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/6077.Sum-of-Total-Strength-of-Wizards) (H) +[2281.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/2281.Sum-of-Total-Strength-of-Wizards) (H) * ``扫描线 / 差分数组`` [252.Meeting-Rooms](https://github.com/wisdompeak/LeetCode/tree/master/Others/252.Meeting-Rooms) (M) [253.Meeting-Rooms-II](https://github.com/wisdompeak/LeetCode/tree/master/Others/253.Meeting-Rooms-II) (M+) From 6e82c3f53d0ad2535296d218372f4d9c4d240caf Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 22:19:28 -0700 Subject: [PATCH 58/62] Update Readme.md --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 127b68195..074dffca3 100644 --- a/Readme.md +++ b/Readme.md @@ -1258,7 +1258,7 @@ [1878.Get-Biggest-Three-Rhombus-Sums-in-a-Grid](https://github.com/wisdompeak/LeetCode/tree/master/Others/1878.Get-Biggest-Three-Rhombus-Sums-in-a-Grid) (M+) [1906.Minimum-Absolute-Difference-Queries](https://github.com/wisdompeak/LeetCode/tree/master/Others/1906.Minimum-Absolute-Difference-Queries) (M+) [2245.Maximum-Trailing-Zeros-in-a-Cornered-Path](https://github.com/wisdompeak/LeetCode/tree/master/Others/2245.Maximum-Trailing-Zeros-in-a-Cornered-Path) (M) -[6077.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/6077.Sum-of-Total-Strength-of-Wizards) (H) +[2281.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/2281.Sum-of-Total-Strength-of-Wizards) (H) * ``2D Presum`` 1314.Matrix-Block-Sum (M) [1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold](https://github.com/wisdompeak/LeetCode/tree/master/Binary_Search/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold) (H-) From 6b77c0ce8097faf1a0aa862bf31f98f81ef12b7c Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 23:27:48 -0700 Subject: [PATCH 59/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index 074dffca3..f6897cad0 100644 --- a/Readme.md +++ b/Readme.md @@ -1217,6 +1217,7 @@ [828.Count-Unique-Characters-of-All-Substrings-of-a-Given-String](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/828.Count-Unique-Characters-of-All-Substrings-of-a-Given-String) (H-) [907.Sum-of-Subarray-Minimums](https://github.com/wisdompeak/LeetCode/tree/master/Stack/907.Sum-of-Subarray-Minimums) (H-) [1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition](https://github.com/wisdompeak/LeetCode/tree/master/Two_Pointers/1498.Number-of-Subsequences-That-Satisfy-the-Given-Sum-Condition) (H-) +[1856.Maximum-Subarray-Min-Product](https://github.com/wisdompeak/LeetCode/tree/master/Stack/1856.Maximum-Subarray-Min-Product) (M+) [2104.Sum-of-Subarray-Ranges](https://github.com/wisdompeak/LeetCode/tree/master/Stack/2104.Sum-of-Subarray-Ranges) (H-) [2262.Total-Appeal-of-A-String](https://github.com/wisdompeak/LeetCode/tree/master/Greedy/2262.Total-Appeal-of-A-String) (M+) [2281.Sum-of-Total-Strength-of-Wizards](https://github.com/wisdompeak/LeetCode/tree/master/Others/2281.Sum-of-Total-Strength-of-Wizards) (H) From 19a16e828eef6237f398bc2afada31a1c8870caf Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 23:49:27 -0700 Subject: [PATCH 60/62] Create 2280.Minimum-Lines-to-Represent-a-Line-Chart.cpp --- ...inimum-Lines-to-Represent-a-Line-Chart.cpp | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/2280.Minimum-Lines-to-Represent-a-Line-Chart.cpp diff --git a/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/2280.Minimum-Lines-to-Represent-a-Line-Chart.cpp b/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/2280.Minimum-Lines-to-Represent-a-Line-Chart.cpp new file mode 100644 index 000000000..5f7c27d29 --- /dev/null +++ b/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/2280.Minimum-Lines-to-Represent-a-Line-Chart.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + int minimumLines(vector>& stockPrices) + { + if (stockPrices.size()==1) return 0; + sort(stockPrices.begin(), stockPrices.end()); + + int ret = 1; + int n = stockPrices.size(); + for (int i=2; i>& stockPrices, int t) + { + int x0 = stockPrices[t-2][0], y0 = stockPrices[t-2][1]; + int x1 = stockPrices[t-1][0], y1 = stockPrices[t-1][1]; + int x2 = stockPrices[t-0][0], y2 = stockPrices[t-0][1]; + + return (long long)(y2-y1)*(x1-x0)==(long long)(y1-y0)*(x2-x1); + } +}; From 7c5183fccf18581bd3b3cedf239d3e5c2a925d7e Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 23:50:05 -0700 Subject: [PATCH 61/62] Update Readme.md --- Readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Readme.md b/Readme.md index f6897cad0..efb79a8fc 100644 --- a/Readme.md +++ b/Readme.md @@ -997,6 +997,7 @@ [1401.Circle-and-Rectangle-Overlapping](https://github.com/wisdompeak/LeetCode/tree/master/Math/1401.Circle-and-Rectangle-Overlapping) (H) [1453.Maximum-Number-of-Darts-Inside-of-a-Circular-Dartboard](https://github.com/wisdompeak/LeetCode/tree/master/Math/1453.Maximum-Number-of-Darts-Inside-of-a-Circular-Dartboard) (H) [1610.Maximum-Number-of-Visible-Points](https://github.com/wisdompeak/LeetCode/tree/master/Math/1610.Maximum-Number-of-Visible-Points) (H) +[2280.Minimum-Lines-to-Represent-a-Line-Chart](https://github.com/wisdompeak/LeetCode/tree/master/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart) (M) * ``Random Pick`` [382.Linked-List-Random-Node](https://github.com/wisdompeak/LeetCode/tree/master/Math/382.Linked-List-Random-Node) (H) [470.Implement-Rand10()-Using-Rand7()](https://github.com/wisdompeak/LeetCode/tree/master/Math/470.Implement-Rand10--Using-Rand7) (M+) From 3b50e512d7ec56c3ad023fbfadb8e3618f3c6b74 Mon Sep 17 00:00:00 2001 From: wisdompeak Date: 2022年5月22日 23:58:53 -0700 Subject: [PATCH 62/62] Create Readme.md --- .../2280.Minimum-Lines-to-Represent-a-Line-Chart/Readme.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/Readme.md diff --git a/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/Readme.md b/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/Readme.md new file mode 100644 index 000000000..998b5a1d6 --- /dev/null +++ b/Math/2280.Minimum-Lines-to-Represent-a-Line-Chart/Readme.md @@ -0,0 +1,7 @@ +### 2280.Minimum-Lines-to-Represent-a-Line-Chart + +将所有点按照横坐标排序之后,本题的核心就是判断任意相邻的三个点ABC是否共线。容易想到,我们判断线段AB和BC的斜率是否相等,即```(y3-y2)/(x3-x2)==(y2-y1)/(x2-x1)```.这里可能会有两个问题,第一个就是精度,当两个小数非常接近时,浮点数很难判断准确。第二个就是当斜率是90度时,除数为0(此题中这个问题不存在)。 + +解决方案就是将除法转换为乘法,即判断```(y3-y2)*(x2-x1)==(y2-y1)*(x3-x2)```即可。 + +相同的技巧在```2152.Minimum-Number-of-Lines-to-Cover-Points```中也用到过。

AltStyle によって変換されたページ (->オリジナル) /