题目链接:454. 四数相加 II - 力扣(LeetCode)
题目描述:
给你四个整数数组 nums1
、nums2
、nums3
和 nums4
,数组长度都是 n
,请你计算有多少个元组 (i, j, k, l)
能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
解题思路:参考代码随想录 (programmercarl.com)
1 class Solution { 2 public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) { 3 int res = 0; 4 Map<Integer,Integer> map = new HashMap<Integer, Integer>(); //创建一个map 5 for (int i : nums1){ 6 for (int j : nums2){ 7 int sum = i + j; 8 map.put(sum, map.getOrDefault(sum, 0) + 1); 9 } 10 } 11 for(int i : nums3){ 12 for (int j : nums4){ 13 res += map.getOrDefault(0-i-j, 0); 14 } 15 } 16 return res; 17 } 18 }
- 在java语言中的Map操作:
Map初始化:
Map<String, String>map = new HashMap<String, String>();
插入元素:
map.put("key1", "value1");
获取元素:
map.get("key1");
移除元素:
map.remove("key1");
清空map:
map.clear();
- hashmap.getOrDefault(Object key, V defaultValue)函数的用法:
参数说明:key - 键、defaultValue - 当指定的key并不存在映射关系中,则返回的默认值。
在题目中使用defaultValue函数对map进行插入,在遍历的过程中a+b的值出现了重复,直接将value值+1,节约了一些时间。
题目描述:
给你两个字符串:ransomNote
和 magazine
,判断 ransomNote
能不能由 magazine
里面的字符构成。
如果可以,返回 true
;否则返回 false
。
magazine
中的每个字符只能在 ransomNote
中使用一次。
解题思路:
这是一个很典型的 字符串a 能否组成 字符串b 的问题——数组在哈希法中的应用。
解题一般分为4步:
1. 定义一个哈希映射的数组record[ ]
2. 遍历 字符串a中出现的字符,并对出现的次数进行计数;
3. 遍历 字符串b中出现的字符,计算 b中出现的字符数-a中出现的字符数
4. 判断 record数组中是否出现负数即b-a<0(也就是说字符串b不能由字符串a所构成)
1 class Solution { 2 public boolean canConstruct(String ransomNote, String magazine) { 3 if (ransomNote.length() > magazine.length()){ 4 return false; 5 //如果ransomNote这个字符串比magazine这个字符串还要长,那magazine必不可能有ransomNote所构成 6 } 7 int[] record = new int[26]; 8 for(char c : magazine.toCharArray()){ 9 record[c - 'a'] += 1; 10 } 11 for(char c : ransomNote.toCharArray()){ 12 record[c - 'a'] -= 1; 13 } 14 for(int i : record){ 15 if(i < 0){ 16 return false; 17 } 18 } 19 return true; 20 } 21 }
toCharArray()方法,将字符串转换为字符数组。
题目描述:
给你一个整数数组 nums
,判断是否存在三元组 [nums[i], nums[j], nums[k]]
满足 i != j
、i != k
且 j != k
,同时还满足 nums[i] + nums[j] + nums[k] == 0
。请
你返回所有和为 0
且不重复的三元组。
注意:答案中不可以包含重复的三元组
解题思路:
因为题目中强调 答案中不可以包含重复的三元组 ,所以要对三元组中的每一个元素进行去重的操作,使用哈希法难以实现,所以采用双指针法。
双指针法:定义一个left指针和right指针。
1. 定义双指针,并将数组从小到大进行排序
2. 根据三数之和对指针进行移动(三数和 > 0, 数偏大,调小,right--;三数和 < 0,数偏小,调大,left++)在这个过程中要对三个元素进行去重的操作。
注意:
对i进行去重:使用的判断条件是nums[i] == nums[i-1]而不是使用nums[i] == nums[i+1],要注意甄别两者的区别。前者是判断i是否有重复,后者是判断三元组中的i是否和left指针所指向的元素有重复。
对left和right去重:在对left和right所对应的元素进行去重的时候,要在收获三元组这个结果之后进行去重,如果从whlie(right>left)这个循环一开始就进行去重的操作,会造成结果的缺失。
1 class Solution { 2 public List<List<Integer>> threeSum(int[] nums) { 3 List<List<Integer>> result = new ArrayList<>(); 4 Arrays.sort(nums); 5 for(int i = 0; i < nums.length; i++){ 6 //排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果即可。 7 if(nums[i] > 0){return result;} 8 //对a去重 9 if(i > 0 && nums[i]==nums[i-1]){continue;} 10 int left = i + 1; 11 int right = nums.length-1; 12 while(right > left){ 13 int sum = nums[i] + nums[left] + nums[right]; 14 if(sum > 0){ 15 right--; 16 } 17 else if(sum < 0){ 18 left++; 19 } 20 else{ 21 result.add(Arrays.asList(nums[i],nums[left],nums[right])); 22 23 while(right > left && nums[right]==nums[right-1])right--; 24 while(right > left && nums[left]==nums[left+1])left++; 25 26 right--; 27 left++; 28 } 29 } 30 } 31 return result; 32 } 33 }
存疑:这个语句不是很懂,还有一些array方法的应用
List<List<Integer>> result = new ArrayList<>();
题目描述:
解题思路:代码随想录 (programmercarl.com)
1 class Solution { 2 public: 3 vector<vector<int>> fourSum(vector<int>& nums, int target) { 4 vector<vector<int>> result; 5 sort(nums.begin(), nums.end()); 6 for (int k = 0; k < nums.size(); k++) { 7 // 剪枝处理 8 if (nums[k] > target && nums[k] >= 0) { 9 break; // 这里使用break,统一通过最后的return返回 10 } 11 // 对nums[k]去重 12 if (k > 0 && nums[k] == nums[k - 1]) { 13 continue; 14 } 15 for (int i = k + 1; i < nums.size(); i++) { 16 // 2级剪枝处理 17 if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) { 18 break; 19 } 20 21 // 对nums[i]去重 22 if (i > k + 1 && nums[i] == nums[i - 1]) { 23 continue; 24 } 25 int left = i + 1; 26 int right = nums.size() - 1; 27 while (right > left) { 28 // nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出 29 if ((long) nums[k] + nums[i] + nums[left] + nums[right] > target) { 30 right--; 31 // nums[k] + nums[i] + nums[left] + nums[right] < target 会溢出 32 } else if ((long) nums[k] + nums[i] + nums[left] + nums[right] < target) { 33 left++; 34 } else { 35 result.push_back(vector<int>{nums[k], nums[i], nums[left], nums[right]}); 36 // 对nums[left]和nums[right]去重 37 while (right > left && nums[right] == nums[right - 1]) right--; 38 while (right > left && nums[left] == nums[left + 1]) left++; 39 40 // 找到答案时,双指针同时收缩 41 right--; 42 left++; 43 } 44 } 45 46 } 47 } 48 return result; 49 } 50 };
标签:map,right,nums,int,day7,++,哈希,left From: https://www.cnblogs.com/inbreak/p/17723735.html