LeetCode:字符串的排列【567】


LeetCode:字符串的排列【567】

題目描述

給定兩個字符串 s1 和 s2,寫一個函數來判斷 s2 是否包含 s1 的排列。

換句話說,第一個字符串的排列之一是第二個字符串的子串。

示例1:

輸入: s1 = "ab" s2 = "eidbaooo"
輸出: True
解釋: s2 包含 s1 的排列之一 ("ba").

 

示例2:

輸入: s1= "ab" s2 = "eidboaoo"
輸出: False

注意:

  1. 輸入的字符串只包含小寫字母
  2. 兩個字符串的長度都在 [1, 10,000] 之間

題目分析

  1.這道題,我們用到的算法是滑動窗口,思路大體是這樣的:

  首先字符串s1的排列的可能性應該是它的長度的階乘,因為字符串長度可能為10000,所以找出所有排列情況是不太可能。我們可以轉換思路,不要關注排列的形式,而是關注排列中元素的數量關系,比如aab,那么,轉換為數量關系就是{a:2,b:1},因為S1長度為3,所以我們的窗口長度也為3,如果我們在S2的找到了這樣一個窗口符合出現a的次數是兩個,b是一個,那么S2就是包含S1的排列的。

  2.什么是滑動窗口啊?

  窗口表示的數組內我們重點關注的一塊范圍,比如此處的范圍是e~i

  

  滑動的意思及時,這個窗口會動,但是窗口的大小不變,比如此時右滑一位時,e就會離開,d就會加入。

  

  3.再來理解一遍題?

  我們說了,不要關注排列的形式,而是關注排列中元素的數量關系,比如aab,那么,轉換為數量關系就是{a:2,b:1},因為S1長度為3,所以我們的窗口長度也為3,如果我們在S2的找到了這樣一個窗口符合出現a的次數是兩個,b是一個,那么S2就是包含S1的排列的。換到這個題中,同理:

  

  所以,輸出為True。 

Java題解

class Solution {
    public boolean checkInclusion(String s1, String s2) {
        int l1 = s1.length();
        int l2 = s2.length();
        int[] c1 = new int[26];
        int[] c2 = new int[26];
        for(char c : s1.toCharArray())
            c1[c-'a']++;
        
        for(int i=0;i<l2;i++)
        {
            if(i>=l1)
                --c2[s2.charAt(i-l1)-'a'];//先把坐標查過的
            c2[s2.charAt(i)-'a']++;
            if(Arrays.equals(c1, c2))
                return true;
        }
        return false;
    }
}

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM