LeetCode - 454. 4Sum II 四数相加II
解题目标:给定四个数组,返回四个数组中分别找出特定位置元素相加得到0的情况的总数
解题思路:这一题不是求每个元素的下标,只需要统计相加等于零的情况的总数。暴力解法就是找出四个数组元素的所有排列组合,最后统计等于0的情况,这样时间复杂度是n^4。实际上可以在这个思路上进一步优化,把前两个数组A[i]+B[j]的元素相加并放入集合,再遍历后两个数组的元素和来对集合里的数进行判断是否有与集合中的元素相加等于0的情况,这样n^2就可以达到目的。
注意事项:为什么是分为两组?这主要是因为这样是可以得到最优的时间复杂度,如果遍历第一个数组再同时查找后三个数组,那么就是n^3。
还有这题必须要用map来进行统计的原因是A+B数组的元素和可能会有不同的排列组合,比如呀1+4,2+3都是5,因此我们的key保存的是前两个数组元素和的值,value应该要保存两数之和出现的次数,判断中应该每次加的是之前所统计的出现次数而不是单纯的加一。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
HashMap<Integer, Integer> records = new HashMap<>();
// record first two arrays' elements sum
for (int i : nums1) {
for (int j : nums2) {
int sum = i + j;
//getOrDefault() 如果有sum这个key则返回value,没有则返回默认值0
records.put(sum, records.getOrDefault(sum, 0) + 1);
}
}
//last two arrays
int count = 0;
for (int k : nums3) {
for (int l: nums4) {
int diff = 0 - (k + l);
count += records.getOrDefault(diff, 0);
}
}
return count;
}
}
LeetCode - 383. Ransome Note
解题目标:给定两个字符串,判断第一个字符串ransomeNote能否用第二个字符串magazine来重新组合得到。
解题思路:和242有效字母异位词的思路很像,这里只需检查第一个字符串在数组所对应的元素。
在第一次写的时候检查哈希表的逻辑用了两层循环,实际上不用另写检查逻辑,可以以magazine为基准先遍历存放在哈希表中,在--的过程中就可以一边检查是否正确,如果减之后为负数,则证明ransomeNote所需的字母不够用,那么一定不符合条件。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) return false;
int[] records = new int[26];
for (int i = 0; i < magazine.length(); i++) {
records[magazine.charAt(i) - 'a']++;
}
for (int j = 0; j < ransomNote.length(); j++) {
records[ransomNote.charAt(j) - 'a']--;
if (records[ransomNote.charAt(j) - 'a'] < 0) return false;
}
return true;
}
}