【Lintcode】211. String Permutation

题目地址:

https://www.lintcode.com/problem/string-permutation/description

给定两个字符串,判断其中一个是否是另一个的排列。可以直接用哈希表来记录其中一个字符串每个字母出现的次数,然后再验证另一个字符串是否是排列即可。代码如下:

import java.util.HashMap;
import java.util.Map;

public class Solution {
    /**
     * @param A: a string
     * @param B: a string
     * @return: a boolean
     */
    public boolean Permutation(String A, String B) {
        // write your code here
        // 如果不一样长,肯定不行,返回false
        if (A.length() != B.length()) {
            return false;
        }
        
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < A.length(); i++) {
        	// 统计A中每个字符和出现次数
            map.put(A.charAt(i), map.getOrDefault(A.charAt(i), 0) + 1);
        }
        for (int i = 0; i < B.length(); i++) {
        	// 如果某个字母B里有但A里没有,那直接返回false
            if (!map.containsKey(B.charAt(i))) {
                return false;
            }
            // 如果有的话,将计数减一
            map.put(B.charAt(i), map.get(B.charAt(i)) - 1);
            // 如果某次计数减一后产生了负数,说明该字母在A和B中出现次数不一样,也返回false
            if (map.get(B.charAt(i)) < 0) {
                return false;
            }
        }
        
        return true;
    }
}

时空复杂度O(n)O(n)

可以简单证明一下程序的正确性。首先几个返回false的地方的正确性是显然的。那么只需要证明如果一直没返回false,那么两个字符串就“构成完全一样”了。反证法,如果构成不完全一样,那么必然存在一个字母在B中出现的次数比A中出现的次数多(因为我们可以把A和B中相同的字符同时删掉,如果A和B构成不一样的话,又因为A和B长度相等,那么必然B会剩下一些字符,这个字符就会出现的次数更多),那么循环里会返回false,这就矛盾了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章