日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Leetcode 76最小覆盖子串77组合78子集

發布時間:2025/3/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Leetcode 76最小覆盖子串77组合78子集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

新人公眾號(求支持):bigsai 專注于Java、數據結構與算法,一起進大廠不迷路!
算法文章題解全部收錄在github倉庫bigsai-algorithm,求star!
關注回復進群即可加入力扣打卡群,歡迎劃水。近期打卡:
LeetCode 67二進制求和&68文本左右對齊&69x的平方根
LeetCode 70爬樓梯&71簡化路徑&72編輯距離(dp)
LeetCode 73矩陣置零&74搜素二維矩陣&75顏色分類
如有幫助,記得對本文一鍵三連!

LeetCode 76最小覆蓋子串

給你一個字符串 s 、一個字符串 t 。返回 s 中涵蓋 t 所有字符的最小子串。如果 s 中不存在涵蓋 t 所有字符的子串,則返回空字符串 “” 。

注意:如果 s 中存在這樣的子串,我們保證它是唯一的答案。

示例 1:

輸入:s = "ADOBECODEBANC", t = "ABC" 輸出:"BANC"

示例 2:

輸入:s = "a", t = "a" 輸出:"a"

提示:

1 <= s.length, t.length <= 105 s 和 t 由英文字母組成

進階:你能設計一個在 o(n) 時間內解決此問題的算法嗎?

問題分析:

題意很清晰,就是要求再s串中找到所有包含t串字符的短串。不考慮存儲我們分析一下該怎么做呢?

常規思路:暴力枚舉,一個字符串有左到右,我只需要從左向右遍歷left,每個left找到最短的right覆蓋t串即可。

但是這樣是一個O(n2)的操作,題目要求用O(n)來完成。該如何做呢? 雙指針
我們可以動態的去覆蓋這個s串,在遍歷的時候遵從一個策略:

  • 選定left的時候,讓right到達最短的那個能夠覆蓋的地方。
  • 下一步將left右移的時候判斷是否能夠滿足覆蓋t串的條件,如果滿足比較下是否需要更新結果,如果不滿足那么將right向右一直找到能夠覆蓋為止。
  • 重復上述一直到結束

但是另一個需要你考慮得問題是,如何統計是否覆蓋呢?
肯定是要通過某種容器,這里哈希肯定是最方便的了,但是我這里不用HashMap 使用2個int []數組分別統計s串和t串中字符出現的個數。

統計t串的可以開始就統計,統計s串的需要統計left和right范圍內的字符。而可以借助一個int類型參數num來統計覆蓋次數:也就是right向右遍歷s串該字符如果比t串中次數少那么加一。如果left向右記錄s串的字符減少如果小于t串中的字符數那么num減少。

具體實現的時候,將字符串轉成字符數組,用左右區間標記替代每次字符串結果來優化時間,可以跑到3ms.
具體的代碼為:

public String minWindow(String s, String t) {int countS[]=new int[150];//用來儲存s中的字符int CountT[]=new int[150];//用來儲存t中的字符char strs[]=s.toCharArray();//轉成數組更快char strt[]=t.toCharArray();for(int i=0;i<strt.length;i++){CountT[strt[i]]++;//計數}String value="";int num=0;//s中擁有t字符 的個數int valueLeft=0,valueRight=strs.length+1;//最終的左右區間范圍int right=0;//right 臨時指針for(int i=0;i<strs.length;i++){if(right==strs.length&&num<strt.length)//已經不可能了 推出{break;}else if (num<strt.length) {//需要往右疊加while (right<strs.length&&num<strt.length) {if(countS[strs[right]]++<CountT[strs[right]])//s這個字符數量小于t中這個字符的數量{num++;}right++;}}//System.out.println("66666 "+right+" "+num);if(num<strt.length&&right==strs.length)//不滿足條件break;if(num==strt.length&&(valueRight-valueLeft>right-i)){valueLeft=i;valueRight=right;}if(countS[s.charAt(i)]--<=CountT[s.charAt(i)])//左側的left右移{num--;}}if(valueRight!=strs.length+1)//如果有滿足的字符串value=s.substring(valueLeft,valueRight);//System.out.println(value);return value;}

LeetCode 77組合

給定兩個整數 n 和 k,返回 1 … n 中所有可能的 k 個數的組合。

示例:

輸入: n = 4, k = 2 輸出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]

所有可能的k個數,經典回溯算法,要考慮兩點:

  • k個數,可以通過一個數字類型來記錄回溯到當前層的數字數量。
  • 重復,避免 ab和ba的情況,對于重復的情況,可以借助一個下標只遍歷下標后面的數字,就可以避免重復。

至于回溯算法的具體設計,老生常談的問題這里就不作過多的復述啦。實現代碼為:

public List<List<Integer>> combine(int n, int k) {List<List<Integer>> valueList=new ArrayList<List<Integer>>();int num[]=new int[n];boolean jud[]=new boolean[n];for(int i=0;i<n;i++){num[i]=i+1;}List<Integer>team=new ArrayList<Integer>();dfs(num,-1,k,valueList,jud,n);return valueList;} private void dfs(int[] num,int index, int count,List<List<Integer>> valueList,boolean jud[],int n) {if(count==0){List<Integer>list=new ArrayList<Integer>();for(int i=0;i<n;i++){if (jud[i]) {list.add(i+1);}}valueList.add(list);}else {for(int i=index+1;i<n;i++){jud[i]=true;dfs(num, i, count-1, valueList,jud,n);jud[i]=false;}}}

性能不算太差但有待優化。

LeetCode78 子集

給定一組不含重復元素的整數數組 nums,返回該數組所有可能的子集(冪集)。

說明:解集不能包含重復的子集。

示例:

輸入: nums = [1,2,3] 輸出: [[3],[1],[2],[1,2,3],[1,3],[2,3],[1,2],[] ]

分析,和上面的思想差不多,不能重復的處理方式是一致的,但是元素個數的話就是在每次回溯的時候都要添加到結果集中。ps:List頻繁插入刪除效率并不高我使用boolean數組進行優化。

具體代碼為

public List<List<Integer>> subsets(int[] nums) {List<List<Integer>> valueList=new ArrayList<List<Integer>>();boolean jud[]=new boolean[nums.length];List<Integer>team=new ArrayList<Integer>();dfs(nums,-1,valueList,jud);return valueList;} private void dfs(int[] num,int index,List<List<Integer>> valueList,boolean jud[]) {{List<Integer>list=new ArrayList<Integer>();for(int i=0;i<num.length;i++){if (jud[i]) {list.add(num[i]);}}valueList.add(list);}{for(int i=index+1;i<num.length;i++){jud[i]=true;dfs(num, i, valueList,jud);jud[i]=false;}} }

結語

原創不易,bigsai請你幫兩件事幫忙一下:

  • star支持一下, 您的肯定是我在平臺創作的源源動力。

  • 微信搜索「bigsai」,關注我的公眾號,不僅免費送你電子書,我還會第一時間在公眾號分享知識技術。加我還可拉你進力扣打卡群一起打卡LeetCode。

  • 記得關注、咱們下次再見!

    總結

    以上是生活随笔為你收集整理的Leetcode 76最小覆盖子串77组合78子集的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。