1.如何创建一个不定长度的数组?
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
List<Ingeter> list = new ArrayList<>();
list.add()
list.add()
list.add()
int[] results = new int[list.size()];
int index = 0;
for(int i:list){
results[index] = i;
index++;
}
}
}
2.二数之和,三数之和,四数之和(涉及哈希表,以及双指针)
2.1二数之和:
分析:查询一个数字是否在集合中,还要知道元素的下标,哈希表是最合适的方式。hashmap。
class Solution {
public int[] twoSum(int[] nums, int target) {
//新建hashmap
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0;i<nums.length;i++){
if(map.containsKey(target-nums[i])){
//发现有哈希表中有符合条件的数字,查询对应的value后直接返回结果。
return new int[]{i,map.get(target-nums[i])};
}else{
//将数组的值和序号挨个填充。
map.put(nums[i],i);
}
}
//如果没有答案,返回一个空数组。
return new int[0];
}
}
2.2 三数之和,并没有要求返回索引,而是数字,而且题目说明不可以包含重复的三元组,因此,使用双指针可能会过更好一点
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> results = new ArrayList<>();
Arrays.sort(nums);
for(int i=0;i<nums.length;i++){
int start = nums[i];
//第一个元素的去重
if(i>0&&nums[i]==nums[i-1]) continue;
//双指针法
int left = i+1;
int right = nums.length-1;
while(right>left){
int sum = start+nums[right]+nums[left];
if(sum>0){
right--;
}else if(sum<0){
left++;
}else {
//将数组转化为list集合
results.add(Arrays.asList(start,nums[right],nums[left]));
//去重
while(right>left&&nums[right]==nums[right-1]) right--;
//去重
while(right>left&&nums[left]==nums[left+1]) left++;
right--;
left++;
}
}
}
return results;
}
}
2.3四数之和(1)一眼哈希,数组的值为key, 出现的次数为value
class Solution {
public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Map<Integer, Integer> map = new HashMap<>();
//俩两遍历,时间复杂度最小
for(int i:nums1){
for(int j:nums2){
//hashmap.put(x,hashmap.getOrDefault(x, 0) 非常优雅的利用hashmap计数的代码
map.put(i+j,map.getOrDefault(i+j,0)+1);
}
}
int res = 0;
for(int i:nums3){
for(int j:nums4){
res = res+map.getOrDefault(-i-j,0);
}
}
return res;
}
}
2.4四数之和(2)
要求不重复的四数之和,还是使用双指针的方法比较合适,思路类似于三数之和。
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums); // 排序数组
List<List<Integer>> results = new ArrayList<>(); // 结果集
for(int i=0;i<nums.length;i++){
int start = nums[i];
//一级剪枝
if(start>=0&&start>target) break;
//一级去重
if(i>0&&nums[i]==nums[i-1]) continue;
for(int j =i+1;j<nums.length;j++){
int second = nums[j];
//二级去重
if(j>i+1&&nums[j]==nums[j-1]) continue;
//二级剪枝
if(second+start>=0&&second+start>target){
break;
}
int left = j+1;
int right = nums.length-1;
while(right>left){
int sum = start+nums[right]+nums[left]+second;
if(sum>target){
right--;
}else if(sum<target){
left++;
}else {
//将数组转化为list集合
results.add(Arrays.asList(start,second,nums[right],nums[left]));
//去重
while(right>left&&nums[right]==nums[right-1]) right--;
//去重
while(right>left&&nums[left]==nums[left+1]) left++;
right--;
left++;
}
}
}
}
return results;
}
}
总结
找索引,计算出现次数,不会有重复的问题的时候,可以采用哈希表。
要求不重复,返回元素的集合的时候,可以考虑用双指针,记得排序。