【算法】 Make Number of Distinct Characters Equal 使字符串总不同字符的数目相等

文章目录

  • Make Number of Distinct Characters Equal 使字符串总不同字符的数目相等
    • 问题描述:
    • 分析
    • 代码
      • BF
      • 改进
    • Tag

Make Number of Distinct Characters Equal 使字符串总不同字符的数目相等

问题描述:

给你两个下标从 0 开始的字符串 word1 和 word2 。

一次 移动 由以下两个步骤组成:

选中两个下标 i 和 j ,分别满足 0 < = i < w o r d 1. l e n g t h 和 0 < = j < w o r d 2. l e n g t h 0 <= i < word1.length 和 0 <= j < word2.length 0<=i<word1.length0<=j<word2.length
交换 word1[i] 和 word2[j] 。
如果可以通过 恰好一次 移动,使 word1 和 word2 中不同字符的数目相等,则返回 true ;否则,返回 false 。

1 < = w o r d 1. l e n g t h , w o r d 2. l e n g t h < = 1 0 5  由小写英文字母组成 1 <= word1.length, word2.length <= 10^5\\\ 由小写英文字母组成 1<=word1.length,word2.length<=105 由小写英文字母组成

分析

要求2个字符串互换一个字符,而且可以使每个字符串的字符种类数相等。

那么首先要做的就是统计,把每个字符串的字符频次统计到map或者array。

至于交换哪2个字符,这个是未知的,有可能有好几对符合,而这里只需要找到任意一个。

所以暴力,毕竟都是小写字母26个。
情况1 交换的是同一类字符
情况2 交换的是非同类字符

每完成一次交换,都对交换后的字符串频次进行统计,验证是否符合要求

这个暴力的时间复杂度就是 O ( 2 6 3 ) O(26^3) O(263),以目前的数据规模是OK的。

其实并不需要每次都进行整个字符的字符频次统计。因为在S1中,要剔除的是字符c1,要加入的是字符c2,如果c1减少到0,那么原始的频次cnt-1,如果c2原来是0,那么cnt+1,以变化量为角度思考,可以在 O ( 1 ) O(1) O(1)的时间复杂度完成验证。
所以整体时间复杂度 O ( 2 6 2 ) O(26^2) O(262)

代码

BF

public boolean isItPossible(String word1, String word2) {
        int[] m1 = new int[26],m2 = new int[26];
        int cnt1 = 0,cnt2 = 0;
        for(int i = 0;i<word1.length();i++){
            m1[word1.charAt(i)-'a']++;
        }
        for(int i = 0;i<word2.length();i++){
            m2[word2.charAt(i)-'a']++;
        }
        //if(check(m1,m1)) return true;
        for(int i = 0;i<26;i++){
            if(m1[i]==0)continue;
            for(int j = 0;j<26;j++){
                if(m2[j]==0) continue;
                m1[j]++;m2[j]--;
                m1[i]--;m2[i]++;
                if(check(m1,m2)){
                    return true;
                }
                m1[i]++;m2[i]--;
                m1[j]--;m2[j]++;
            }
        }
        return false;
    }
    public boolean check(int[] A,int[] B){
        int cnt1 = 0,cnt2 = 0;
        for(int i=0;i<A.length;i++){
            if(A[i]!=0) cnt1++;
        }
        for(int i=0;i<B.length;i++){
            if(B[i]!=0) cnt2++;
        }
        return cnt1==cnt2;
    }

时间复杂度 O ( ( 字符量 ) 3 ) O((字符量)^3) O((字符量)3)

空间复杂度 O ( 字符量 ) O(字符量) O(字符量)

改进

public boolean isItPossible(String word1, String word2) {
        int[] m1 = new int[26],m2 = new int[26]; 
        int cnt1 = 0,cnt2 = 0;               
        for(int i = 0;i<word1.length();i++){
            m1[word1.charAt(i)-'a']++;
            if(m1[word1.charAt(i)-'a']==1) cnt1++;
        }
        for(int i = 0;i<word2.length();i++){
            m2[word2.charAt(i)-'a']++;
            if(m2[word2.charAt(i)-'a']==1) cnt2++;
        } 
        for(int i = 0;i<26;i++){
            if(m1[i]==0)continue;
            for(int j = 0;j<26;j++){
                if(m2[j]==0) continue;
                if(i==j){
                    if(cnt1==cnt2) return true;
                    continue;
                }
                int d1 = 0,d2 = 0;
                if(m1[i]==1) d1--;
                if(m1[j]==0) d1++;
                if(m2[j]==1) d2--;
                if(m2[i]==0) d2++;
                if(cnt1+d1==cnt2+d2) return true;
            }
        }
        return false;
    }

时间复杂度 O ( ( 字符量 ) 2 ) O((字符量)^2) O((字符量)2)

空间复杂度 O ( 字符量 ) O(字符量) O(字符量)

Tag

String

Hash

Counting

你可能感兴趣的:(数据结构与算法,算法,数据结构)