題目地址:
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;
}
}
時空複雜度。
可以簡單證明一下程序的正確性。首先幾個返回false的地方的正確性是顯然的。那麼只需要證明如果一直沒返回false,那麼兩個字符串就“構成完全一樣”了。反證法,如果構成不完全一樣,那麼必然存在一個字母在B中出現的次數比A中出現的次數多(因爲我們可以把A和B中相同的字符同時刪掉,如果A和B構成不一樣的話,又因爲A和B長度相等,那麼必然B會剩下一些字符,這個字符就會出現的次數更多),那麼循環裏會返回false,這就矛盾了。