四数相加Ⅱ LeetCode 454
题目链接:[LeetCode 454 - 中等]
思路
考虑了之前的两数相加,并且可能存在不同的数相加后得到相同数的情况,因此使用HashMap。
HashMap:
java
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer,Integer> map = new HashMap<>();
int result = 0;
for(int num1:nums1){
for(int num2:nums2){
map.put(num1+num2,map.getOrDefault(num1+num2,0)+1);
}
}
for(int num3:nums3){
for(int num4:nums4){
if(map.containsKey(-num3-num4)){
result += map.get(-num3-num4);
}
}
}
return result;
}
}
总结
使用了之前的题目中学到的知识
赎金信 LeetCode 383
题目链接:[LeetCode 383 - 简单]
思路
第一想法是使用HashMap,原因如下:题目中magazine中的每个字符只能在ransomNote中,因此相同的字符的个数也需要记录。
HashMap:
java
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
HashMap<Character,Integer> map = new HashMap<>();
for(int i=0;i<magazine.length();i++){
char ch = magazine.charAt(i);
map.put(ch,map.getOrDefault(ch,0)+1);
}
for(int i=0;i<ransomNote.length();i++){
char ch = ransomNote.charAt(i);
if(!map.containsKey(ch)){
return false;
}else{
map.put(ch,map.get(ch)-1);
if(map.get(ch)<0){
return false;
}
}
}
return true;
}
}
总结
- 看了更高效的解题时,发现该题可以参考#242有效的字母异位词的方式,即采用数组作为哈希表。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
int[] recond = new int[26];
for(int i=0;i<magazine.length();i++){
char ch = magazine.charAt(i);
recond[ch - 'a']++;
}
for(int i=0;i<ransomNote.length();i++){
char ch = ransomNote.charAt(i);
if(recond[ch - 'a']==0)
return false;
recond[ch - 'a']--;
}
return true;
}
}
代码可以优化:
for(char ch:magazine.toCharArray()){
recond[ch - 'a']++;
}
- 该解法也可以代码优化:
for(int i=0;i<ransomNote.length();i++){
char ch = ransomNote.charAt(i);
if(!map.containsKey(ch)){
return false;
}else{
map.put(ch,map.get(ch)-1);
if(map.get(ch)<0){
return false;
}
}
}
改为
for(int i=0;i<ransomNote.length();i++){
int v=map.getOrDefault(ransomNote.charAt(i),0);
if(v == 0)
return false;
map.put(ransomNote.charAt(i),v-1);
}
三数之和 LeetCode 15
题目链接:[LeetCode 15 - 中等]
思路
看到题目,有一些想法 ①需要对原数组进行排序 ②需要进行去重操作
O(n^2):
java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>0)
return result;
if(i>0 && nums[i]==nums[i-1])
continue;
int left=i+1;
int right=nums.length-1;
while(left<right){
if(nums[i]+nums[left]+nums[right]==0){
result.add(Arrays.asList(nums[i],nums[left],nums[right]));
while(left<right && nums[left]==nums[left+1])left++;
while(left<right && nums[right]==nums[right-1])right--;
left++;
right--;
}else if(nums[i]+nums[left]+nums[right]>0){
right--;
}else{
left++;
}
}
}
return result;
}
}
总结
- 如何进行排序
Arrays.sort(nums);
- 如何进行去重操作
if(i>0 && nums[i]==nums[i-1]) continue;
while(left<right && nums[left]==nums[left+1])left++;
while(left<right && nums[right]==nums[right-1])right--;
- 代码的巧妙之处:简短的一句代码精简了循环,将=0的隐含的内容囊括。
if(nums[i]>0)return result;
四数之和 LeetCode 18
题目链接:[LeetCode 18 - 中等]
思路
看到题目,感觉和#15三数相加差不多,有一些想法 ①需要对原数组进行排序 ②需要进行去重操作 但是有一些需要注意的地方,在第二个for循环的时候,需要剪枝。
O(n^3):
java
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> result = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
if(nums[i]>0 && nums[i]>target)return result;
if(i>0 && nums[i]==nums[i-1]){
continue;
}
for(int j=i+1;j<nums.length;j++){
if(j>i+1 && nums[j]==nums[j-1]){
continue;
}
int left = j+1;
int right = nums.length-1;
while(left<right){
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if(sum==target){
result.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
while(left<right && nums[left]==nums[left+1])left++;
while(left<right && nums[right]==nums[right-1])right--;
left++;
right--;
}else if(sum>target){
right--;
}else if(sum<target){
left++;
}
}
}
}
return result;
}
}
总结
- 非常重要的代码:long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];如果是int,会导致溢出