最近準備面試,我以前不愿意面對的
現在保持一顆本心,就是專注于算法思想,語言基礎的磨煉;
不為速成,不急功近利的想要比賽,或者為了面試。
單純的本心,體驗算法帶來的快樂,是一件非常了不起的事。
加油,持續輸出~
戰勝恐懼最好的方法,就是面對
一、滑動窗口
1.1 最小覆蓋子串
集成度越高的結構體(unordered_map)再使用上雖然方便,但遇到多次循環處理,處理速度不如用vector維護的可變數組;
把兩組映射轉換為一個數組,非常巧妙;
運行速度真的是見仁見電腦嗎?我參考的1ms 的寫法,甚至把他的源碼,放我的LeetCode提交,我的最快也還是3ms。
(想到了飛馳人生2,雖然比不上專業賽車,只要你苦練技術,一定可以超越自己)
/*滑動窗口 O(1)
對于一個數組、字符串、鏈表 原串 s 目標串 t 最終結果 res
定義兩個hash map: hs 負責記錄滑動窗口,ht 負責目標串
定義i,j兩個指針,i負責擴展,滿足條件 cnt 計數器++
j負責縮圈 當滿足條件,j--
*/
//模板
string minWindow(string s, string t) {unordered_map<char, int> hs, ht;for(auto a : t)ht[a]++;int cnt = 0;string res = "";for(int i=0, j=0; i < s.size(); i++){hs[s[i]]++;if(hs[s[i]] <= ht[s[i]])//條件可根據實際發生變化cnt++;while(hs[s[j]] > ht[s[j]]) //縮圈hs[s[j++]]--;if(cnt == t.size() && (res == ""||res.size() > (i-j+1))){//條件根據實際情況res = s.substr(j, i-j+1);}}return res;
}
對于字符串也可以用vector, 更節省時間string minWindow(string s, string t) {//unordered_map<char, int> hs, ht;vector<int> ht(128,0);for(auto a : t)ht[a]++;int cnt = 0;//string res = "";int rlen = INT_MAX;int len = t.size();int i=0, j=0, rj = 0, ri = 0;for(; i < s.size(); i++){//hs[s[i]]++;//if(hs[s[i]] <= ht[s[i]])char c = s[i];if(ht[c] > 0){cnt++;} ht[c]--; //每個字符都減掉,如果是目標字符都是0,說明找到了,如果是-1 說明遇到重復的了需要縮圈//while(hs[s[j]] > ht[s[j]]) // hs[s[j++]]--;if(cnt == len) {while(ht[s[j]]<0){ht[s[j]]++;//把多減掉的不回來j++; //指針往后移動,繼續縮圈,就是刪掉不用重復的字符} if(rlen > (i-j+1)) //更新目標子串{rlen = (i-j+1);ri = i;rj = j;}}}if(rlen != INT_MAX)return s.substr(rj, ri-rj+1);elsereturn ""; }
1.2 長度最小子數組
輸入輸出流的取消能快很多+一些特殊判斷
auto optimize_cpp_stdio=[](){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);return 0;
}();
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int hs = 0;int nlen = nums.size();int len = nlen + 1;for(int i=0,j=0; i < nlen; i++){hs+= nums[i]; while(hs-nums[j] >= target){hs=hs-nums[j]; j++;} if(hs >= target && len > i-j+1)len = i-j+1;if(len == 1)return 1;}if(len!=nlen+1)return len;elsereturn 0;}
};