454.四数相加II
这道题主要学到两点,这道题我一开始根本看不出来要用到哈希表,
第一点:听了视频讲解知道了,而且我还发现就算知道了要用到哈希表,我也不知道怎么使用,现在明白了,哈希表就是要找有没有你需要的元素,在这道题当中,四个数字,总不能找四个哈希表,所以前两个相加创建一个哈希表,后两个相加得到一个数,利用这个数就到前面得到的哈希表里面去找值。算是给我开拓了一个思路。
第二点:学到了map.getOrDefault函数的使用。http://t.csdnimg.cn/aYZm1这是链接。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer,Integer> map = new HashMap<>();
int sum = 0;
for(int i = 0;i<nums1.length;i++){
for(int j = 0;j<nums2.length;j++){
sum = nums1[i]+nums2[j];
map.put(sum,map.getOrDefault(sum,0)+1);
}
}
int count =0;
for(int i = 0;i<nums3.length;i++){
for(int j = 0;j<nums4.length;j++){
sum = nums3[i]+nums4[j];
count += map.getOrDefault(0-sum,0);
}
}
return count;
}
}
383. 赎金信
和242. 有效的字母异位词很像,第一次就通过了。
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] hash = new int[26];
for(int i=0 ; i<magazine.length();i++){
hash[magazine.charAt(i)-'a']++;
}
for(int j = 0;j<ransomNote.length();j++){
hash[ransomNote.charAt(j)-'a']--;
}
for(int k = 0;k<hash.length;k++){
if(hash[k]<0){
return false;
}
}
return true;
}
}
15. 三数之和
这道题对我来说比较难,想了很久。卡尔的视频去重那部分有些没听懂。找了一个别的视频,他是从两数之和扩展到三数之和的,比较有参考意义。相向双指针法。【LeetCode 每日一题】15. 三数之和 | 手写图解版思路 + 代码讲解_哔哩哔哩_bilibili
两数之和 三数之和【基础算法精讲 01】_哔哩哔哩_bilibili
i是看是否与前一个重复,而l和r是看是否与下一个重复,nums[l]+nums[r]>target这个比较好理解
大于target,那么r就-1;
我总是忘了去重,要重点关注。
总忘了排序。
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 (i > 0 && nums[i] == nums[i - 1]) { // 去重a
continue;
}
int l = i+1;
int r = nums.length-1;
while(l<r){
int target = 0- nums[i];
if(nums[l]+nums[r]>target){
r--;
}else if(nums[l]+nums[r]<target){
l++;
}else{
result.add(Arrays.asList(nums[i],nums[l],nums[r]));
while(l<r&&nums[l]==nums[l+1]) l++;
while(l<r&&nums[r]==nums[r-1]) r--;
l++;
r--;
}
}
}
return result;
}
}
18. 四数之和
一开始没想到可以用双层循环,那么从这道题就可以扩展到五数、六数了。
还是出现了和三数之和一样的问题,忘了排序,忘了i和j的去重,
剩下的没什么大问题,唯一要注意的是sum要变成long。
还有就是剪枝问题,不剪的话速度就是会慢一些,并不会影响结果,剪了的话比较难理解,我先不剪,方便理解。
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(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 l = j+1;
int r = nums.length-1;
while(l<r){
long sum =(long) nums[i]+nums[j]+nums[l]+nums[r];/一开始写在了while循环外面,是错的。
if(sum<target){
l++;
}else if(sum>target){
r--;
}else{
result.add(Arrays.asList(nums[i],nums[j],nums[l],nums[r]));
while(l<r&&nums[l]==nums[l+1]){
l++;
}
while(l<r&&nums[r]==nums[r-1]){
r--;
}
l++;
r--;
}
}
}
}
return result;
}
}
167. 两数之和 II - 输入有序数组
我觉得应该先把这道题安排上,这道题是基础。直接返回普通数组就行。不用声明ArrayList。
class Solution {
public int[] twoSum(int[] numbers, int target) {
int l = 0;
int r = numbers.length-1;
while(l<r){
int sum = numbers[l] + numbers[r];
if(sum == target){
return new int[]{l+1,r+1};
}else if(sum<target){
l++;
}else{
r--;
}
}
return new int[]{1,1};
}
}