1.两数之和
思路:本题使用hashmap,因为题目要求返回的是下标,我们需要同时存放值和下标。
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] ans =new int[2];
if(nums.length==0) return ans;
//因为要存放key,val
Map<Integer,Integer> map = new HashMap<>();//创建一个哈希map
for(int i=0;i<nums.length;i++){
int temp = target-nums[i];
if(map.containsKey(temp)){//测试是否包含temp这个值
ans[0]=i;
ans[1]=map.get(temp);//获得temp的映射
}
map.put(nums[i],i);
}
return ans;
}
}
2.四数相加
思路:
1.两两相加,分成两组,然后判断两组和是否为0
2.我们使用map,因为我们不仅要记录数字之和,我们还要记录出现的次数。
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer,Integer> map = new HashMap<>();
int ans =0;//用于记录满足条件的值
int temp =0;//两个数组相加的值
//记录两个数组的元素之和,且统计相同的值出现的次数,放入map
for(int i:nums1){
for(int j:nums2){
temp=i+j;
if(map.containsKey(temp)){
map.put(temp,map.get(temp)+1);
}
else{
map.put(temp,1);//记录为第一次出现
}
}
}
//统计后两个数组的元素之和,并在map中寻找是否和为0,同时记录次数
for(int i:nums3){
for(int j:nums4){
temp=0-i-j;
if(map.containsKey(temp)){
ans +=map.get(temp);//获得次数
}
}
}
return ans;
}
}
3.三数之和
思路:
1.此题必须先进行排序。
2.先固定一个数字,然后以该数为基准,从下一个数开始循环判断。
3.注意去重的时机。
4.注意Arrays.asList()的应用。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans =new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
//对于排序后的数组,如果当前数字大于0,则退出当前循环
if(nums[i]>0){
return ans;
}
//去重,避免同一个数字使用两次
if(i>0&&nums[i]==nums[i-1]){
continue;
}
//以nums[i]为参照物,进行循环判断
int left = i+1;//当前值的下一位
int right =nums.length-1;
while(left<right){//不能等于是因为同一个值不能使用两次
int sum =nums[i]+nums[left]+nums[right];
if(sum>0){
right--;
}
else if(sum<0){
left++;
}
else{
ans.add(Arrays.asList(nums[i],nums[left],nums[right]));
//去重,因为答案中不能包含相同的三元组
while(right>left&&nums[right]==nums[right-1]) right--;
while(right>left&&nums[left]==nums[left+1]) left++;
left++;
right--;
}
}
}
return ans;
}
}
4.四数之和
思路:
和上题一致,但是需要以两个值为基准。。
class Solution {
//将两个值作为基准,使用双指针循环
public List<List<Integer>> fourSum(int[] nums, int target) {
List <List<Integer>> ans =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 left = j+1;//当前值的下一位
int right =nums.length-1;
while(left<right){
int sum =nums[i]+nums[j]+nums[left]+nums[right];
if(sum>target) {
right--;
}
else if(sum<target) {
left++;
}
else if(sum==target){
ans.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
//去重,防止出现重复数组
while(left<right&&nums[right]==nums[right-1]) right--;
while(left<right&&nums[left]==nums[left+1]) left++;
right--;
left++;
}
}
}
}
return ans;
}
}