leetcode常用算法,leetcode ---雙指針+滑動窗體

 2023-11-19 阅读 24 评论 0

摘要:一:Minimum Size Subarray Sum(最小長度子數組的和O(N)) 題目: Given an array of?n?positive integers and a positive integer?s, find the minimal length of a subarray of which the sum ≥?s. If there isn't one, return 0 instead.

一:Minimum Size Subarray Sum(最小長度子數組的和O(N))

題目:

Given an array of?n?positive integers and a positive integer?s, find the minimal length of a subarray of which the sum ≥?s. If there isn't one, return 0 instead.

For example, given the array?[2,3,1,2,4,3]?and?s = 7,
the subarray?[4,3]?has the minimal length under the problem constraint.

分析:一開始我採用的是LIS(longest increased sequence)中的最長遞增子序列中的動態規劃的思想。能通過,可是時間復雜度為O(N

^2);。;另外一種方法是採用雙指針+滑動窗體的思想。時間復雜度為O(N)。 嚴格意義上說是2N。,比方 [1,2,3,15,3,4,5,15] s=14,,,僅僅有在15處將前面的元素又又一次加了一遍,故為2N

初始快慢指針都為0,fast指針向前移動。當slow和fast中連續字數組的和大于s時。我們就開始縮減窗體,不斷的對slow進行向前移動直到sum小于s,然后再移動fast繼續循環

代碼:

class Solution {
public:// 法一/*int minSubArrayLen(int s, vector<int>& nums) {int result = nums.size();bool flag = false;for(int i = 0; i < nums.size(); i++){if(nums[i] >= s) return 1;int sum = nums[i];for(int j = i-1; j >= 0; j--){sum += nums[j];if(sum >= s){result = min(result, i-j+1);flag = true;break;}}}if(flag)return result;return 0;}*/int minSubArrayLen(int s, vector<int>& nums) {     // 滑動窗體的形式+雙指針int result = nums.size()+1;int frontPoint = 0, sum = 0;for(int i = 0; i < nums.size(); i++){sum += nums[i];while(sum >= s){    // 找到了窗體result = min(result, i - frontPoint + 1);   // 窗體是否滿足要求sum -= nums[frontPoint++];            // 縮減窗體}}return result == (nums.size()+1) ?

0:result; } };


leetcode常用算法、二:Minimum Window Substring

題目:

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

For example,
S?=?"ADOBECODEBANC"
T?=?"ABC"

Minimum window is?"BANC".

Note:
If there is no such window in S that covers all characters in T, return the emtpy string?"".

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.

分析:這道題剛開始我採用類似于上面滑動窗體的方法,可是每次都要推斷當前字符串中是否全然包括字符串t,這個推斷就會提升時間復雜度,結果導致TLE。后面參看了discuss中的方法,很巧妙,也放在這里。代碼中map用來存放t字符串中的字符及出現的次數,而window用來存放字符串t中每一個字符在字符串s中出現的次數。lettercounts是一個標記變量,當等于t.size()的時候。就表示得到了一個全然包括t的字符子串。然后移動慢指針縮減窗體。

代碼:

leetcode算法,TLE:

class Solution {
public:bool isContain(const string &sstr, const string &t){for(int i = 0; i < t.size(); i++){if(sstr.find_first_of(t[i]) == string::npos) return false;}return true;}string minWindow(string s, string t) {int result = s.size()+1, frontPoint = 0;string str="";for(int i = 0; i < s.size(); i++){while(isContain(s.substr(frontPoint, i-frontPoint+1) , t)){if(result > i-frontPoint+1){result = i-frontPoint+1;str = s.substr(frontPoint, i-frontPoint+1);}frontPoint++;}}return str;}
};

AC代碼:

class Solution {
public:string minWindow(string s, string t) {string result;if(s.size() == 0 || t.size() == 0) return result;unordered_map<char, int> map;unordered_map<char, int> window;  // 滑動窗體int lettercounts = 0;               // 標記變量,當等于t.size()的時候。該窗體就是一個全然包括字符串t的子串int minLen = s.size()+1;for(int i = 0; i < t.size(); i++)  // 將t放入map中。就是為了加速map[t[i]]++;for(int fast = 0, slow = 0; fast < s.size(); fast++){  // 快慢指針,快指針不斷向前移動,char c = s[fast];if(map.find(c) != map.end()){      // window[c]++;if(window[c] <= map[c]){      // 變化lettercount變量lettercounts ++;}if(lettercounts >= t.size()){           // 表示該窗體中已經所有包括t了while(map.find(s[slow]) == map.end() || window[s[slow]] > map[s[slow]]){  // 對窗體進行縮減  1:slow所指向字符不在map中,2:在該子串中                                                                                               //出現非常多次  如BBABC    ABC slow指向Bwindow[s[slow]]--;slow++;}if(minLen > fast - slow + 1){    minLen = fast - slow + 1;result = s.substr(slow, minLen);}window[s[slow]]--;     // 縮減窗體slow++;lettercounts --;}}}return result;}
};

leetcode java?三:Contains Duplicate III

題目:

Given an array of integers, find out whether there are two distinct indices?i?and?j?in the array such that the difference between?nums[i]?and?nums[j]?is at most?t?and the difference between?i?and?j?is at most?k.

分析:這道題目也是滑動窗體,滑動窗體一般都是定義一個slow指針,然后一個fast指針不斷向前滑動(循環遍歷)。這個過程中我們要推斷1:是否找到了窗體,2:窗體時否滿足要求 3:窗體縮減等

leetcode c語言,此題也是,設置慢指針l,和快指針i遍歷,窗體過大就縮減,判斷找到的窗體是否滿足要求,技巧是用到了關聯容器的lower_bound函數,假設滿足要求就返回true,否則返回false。

這里用set或者multiset都一樣.。

注意這里的auto是c++11的新特性。能夠用來自己主動類型判斷!

leetcode反轉鏈表。

class Solution {
public:/*bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {if(nums.size() < 2 || k == 0) return false;multiset<long> windows;       // 滑動窗體int l = 0;for(int i = 0; i < nums.size(); i++){if(i - l > k){     // 窗體大小超過了k 則須要刪除nums[l]而且l++windows.erase(nums[l++]);}auto it = windows.lower_bound((long)nums[i] - (long)t);if(it != windows.end() && *it <= ((long)nums[i]+(long)t))    // 用long防止+1溢出return true;windows.insert(nums[i]);}return false;}*/bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {if(nums.size() < 2 || k == 0) return false;set<long> windows;       // 滑動窗體int l = 0;               // 慢指針for(int i = 0; i < nums.size(); i++){if(i - l > k){     // 窗體大小超過了k 則須要刪除nums[l]而且l++  窗體須要縮減了windows.erase(nums[l++]);}auto it = windows.lower_bound((long)nums[i] - (long)t);      //  即為nums[i]-t與nums[i]+t之間是否有元素       if(it != windows.end() && *it <= ((long)nums[i]+(long)t))    // 用long防止+1溢出  找到了return true;windows.insert(nums[i]);             // not found}return false;}
};



leetcode c++、

轉載于:https://www.cnblogs.com/yangykaifa/p/6723092.html

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/180075.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息