給你一個僅由大寫英文字母組成的字符串,你能夠將任意位置上的字符替換成另外的字符,總共可最多替換 k 次。在執行上述操做後,找到包含重複字母的最長子串的長度。css
若是咱們按序遍歷每一個字符開始計算符合條件的子串長度,對於每一個子串,咱們只須要以它的第一個字符爲不變字符。思路簡單,代碼清晰,耗時巨長,加了一個遇連續相同字符直接跳過,以及i到達的字符開始的子串不可能爲最大時結束,才勉強AC數組
int characterReplacement(string s, int k) { int n=s.length(); int ans=0; for(int i=0;i<s.length();i++){ if(i>0&&s[i]==s[i-1])continue; if(s.length()-i+k<=ans)return ans; char c=s[i]; int tmp=0; for(int j=i+1;j<s.length();j++){ if(s[j]!=c)tmp++; if(tmp>k){ ans=max(ans,j-i); break; } } if(tmp<=k) ans=max(ans,min((int)s.length(),(int)s.length()-i+k-tmp)); } return ans; }
這題是典型的雙指針問題,或者,滑動窗口問題。不須要保存每個窗口內的字母出現的最大值,由於字母必定是從右邊新添的字符裏出現,並且只有當窗口內出現了比歷史更多的字母數時,答案纔會更新,也就是maxCnt不須要是實時的最大字母數。oop
int characterReplacement(string s, int k) { int n=s.length(); int ans=0,left=0,maxCnt=0; vector<int> letter(26,0); for(int i=0;i<s.length();i++){ letter[s[i]-'A']++; maxCnt=max(maxCnt,letter[s[i]-'A']); if(i-left+1-maxCnt>k){ letter[s[left]-'A']--; left++; } ans=max(ans,i-left+1); } return ans; }
給定一個含有正整數和負整數的環形數組 nums。 若是某個索引中的數 k 爲正數,則向前移動 k 個索引。相反,若是是負數 (-k),則向後移動 k 個索引。由於數組是環形的,因此能夠假設最後一個元素的下一個元素是第一個元素,而第一個元素的前一個元素是最後一個元素。spa
肯定 nums 中是否存在循環(或週期)。循環必須在相同的索引處開始和結束而且循環長度 > 1。此外,一個循環中的全部運動都必須沿着同一方向進行。換句話說,一個循環中不能同時包括向前的運動和向後的運動。指針
原方法:code
用一個數組vis記錄
vis[i]=k表示 結點 i 是從下標 k 爲起始點出發所能到達的路徑上的點
每次從未探索過的i出發找大於1的環blog
bool circularArrayLoop(vector<int>& nums) { int n=nums.size(); vector<int> vis(n,-1); for(int i=0;i<n;i++) { if(vis[i]>=0&&vis[i]<i)continue; int t=i; bool flag=nums[i]>0?true:false; while(flag==(nums[t]>0)){ //flag保證同方向 if(vis[t]==i){ int len=0; int k=(t+nums[t]+n)%n; while(k<0)k=(k+n); //保證下標爲正 while(k!=t){ k=(k+nums[k]+n)%n; while(k<0) k=(k+n); len++; if(len>0) return true; } //計算環的長度 break; //從i出發僅有1單位長度的環,繼續從i+1開始找 } if(vis[t]!=-1)break; //跑到以前走過的路上去了,以前無解,此次也無解 vis[t]=i; t=(t+n+nums[t])%n; while(t<0)t=(t+n); } } return false; }
改進方法:既然是雙指針的問題,又有環,那快慢指針確定沒跑了索引
int idx(int i, int dx,int n){ if(dx>0)return (i+dx)%n; else return (i-abs(dx)%n+n)%n; } bool circularArrayLoop(vector<int>& nums) { int n=nums.size(); vector<int> vis(n,-1); for(int i=0;i<n;i++) { if(vis[i]!=-1)continue; int slow=i,fast=i; while(nums[slow]*nums[fast]>0&&nums[slow]*nums[idx(fast,nums[fast],n)]>0){ slow=idx(slow,nums[slow],n); if(vis[slow]!=-1&&vis[slow]!=i)break;vis[slow]=i; fast=idx(fast,nums[fast],n); if(vis[fast]!=-1&&vis[fast]!=i)break;vis[fast]=i; fast=idx(fast,nums[fast],n); if(vis[fast]!=-1&&vis[fast]!=i)break;vis[fast]=i; if(fast==slow){ if(idx(slow,nums[slow],n)!=slow)return true; break; } } } return false; }
待更新。。。ci