LeetCode1160.拼寫單詞(Java+暴力+HashMap)

Fiona Tracy發表於2020-12-15

題目

給你一份『詞彙表』(字串陣列) words 和一張『字母表』(字串) chars。 假如你可以用 chars 中的『字母』(字元)拼寫出 words 中的某個『單詞』(字串),那麼我們就認為你掌握了這個單詞。
注意:每次拼寫(指拼寫詞彙表中的一個單詞)時,chars 中的每個字母都只能用一次。 返回詞彙表 words 中你掌握的所有單詞的 長度之和。

輸入:words = [“cat”,“bt”,“hat”,“tree”],
chars = “atach”
輸出:6
解釋 可以形成字串 “cat” 和 “hat”,所以答案是 3 + 3 = 6。

方法一:暴力解

主要是處理“chars 中的每個字母都只能用一次”

// 三重迴圈,太慢了
	static public int countCharacters(String[] words, String chars) {
		int sum = 0;
		HashSet<Integer> set = new HashSet<>();
		for (String str : words) {
			for (int i = 0; i < str.length(); i++) {
				for (int j = 0; j < chars.length(); j++) {
					if (set.contains(j)) {
						continue;
					} else {
						if (str.charAt(i) == chars.charAt(j)) {
							set.add(j);
							break;
						}
					}
				}
			}
			if (set.size() == str.length()) {
				sum += set.size();
			}
			set.clear();
		}
		return sum;
	}

方法二:HashMap

設兩個HashMap,分別儲存每個字串的字元數量,然後進行比較大小

static public int countCharacters2(String[] words, String chars) {
		// 前面字元,後面個數
		HashMap<Character, Integer> map = new HashMap<>();// 放chars
		HashMap<Character, Integer> mapOfArray = new HashMap<>();// 放words
		int sum = 0;
		// 先放chars
		for (int i = 0; i < chars.length(); i++) {
			map.put(chars.charAt(i), map.getOrDefault(chars.charAt(i), 0) + 1);
		}
		for (String str : words) {
			for (int i = 0; i < str.length(); i++) {
				mapOfArray.put(str.charAt(i), mapOfArray.getOrDefault(str.charAt(i), 0) + 1);
			}
			boolean flag = true;
			// 改進
			// for (int i = 0; i < str.length(); i++) {
			// if (!map.containsKey(str.charAt(i))||map.get(str.charAt(i)) <
			// mapOfArray.get(str.charAt(i))) {
			// flag = false;
			// }
			// }
			for (int i = 0; i < str.length(); i++) {
				char temp = str.charAt(i);
				if (map.getOrDefault(temp, 0) < mapOfArray.getOrDefault(temp, 0)) {
					flag = false;
					break;
				}
			}
			if (flag) {
				sum += str.length();
			}
			mapOfArray.clear();
		}
		return sum;
	}

發現

程式碼1:

for (int i = 0; i < str.length(); i++) {
			if (!map.containsKey(str.charAt(i)) || map.get(str.charAt(i)) < mapOfArray.get(str.charAt(i))) {
				flag = false;
			}
		}

程式碼2:

for (int i = 0; i < str.length(); i++) {
		char temp = str.charAt(i);
			if (map.getOrDefault(temp, 0) < mapOfArray.getOrDefault(temp, 0)) {
				flag = false;
				break;
			}
		}

程式碼1VS程式碼2:程式碼2 會快很多!!
原因是:map.get(str.charAt(i)),要執行:str先取出第i個字元,再給map去查詢,會慢很多。
所以先設定一個temp變數,儲存字元,用temp去代替map.get中的str.charAt()。

比較兩個map個value,可以用getOrDefault()方法來進行比較。

反思

多思考啊!!加油呀

相關文章