系列文章目录
刷题笔记(一)–数组类型:二分法
刷题笔记(二)–数组类型:双指针法
刷题笔记(三)–数组类型:滑动窗口
刷题笔记(四)–数组类型:模拟
刷题笔记(五)–链表类型:基础题目以及操作
刷题笔记(六)–哈希表:基础题目和思想
刷题笔记(七)–字符串:经典题目
题录
这里在正式引申之前说一下,双指针法是一种应用很广的方法,像我们前面的数组,链表,字符串等等,很多问题都是使用双指针法来解决。具体的可以看我之前的博客,这篇博客主要就是对两数之和问题做一个拓展。
两数之和
题目链接如下:
截屏如下:
是不是很眼熟,之前我们是不是做过对应的题目?第一种解法就是暴力遍历,第二种就是用一个哈希表来记录映射关系。
import java.util.HashMap;
public class 两数之和 {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap = new HashMap();
for (int i = 0; i < nums.length; i++) {
if(hashMap.containsKey(target-nums[i])){
return new int[]{i,hashMap.get(target-nums[i])};
}
hashMap.put(nums[i],i);
}
return null;
}
}
三数之和
题目链接如下:
题目截屏如下:
这个题目是很有意思的,因为三数之和,总体思路就是在二数之和的基础上做一个延伸,也就是在确定一个数的情况下,寻找另外两数之和等于0 - (当前已确定数)。但是具体细节还是要仔细敲定一下的。也幸好不是返回下标,不然更麻烦。
public class 三数之和 {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < nums.length - 2; i++) {//如果这个时候就剩下两个元素就没有必要再遍历了
//我们是从前往后遍历的,而且是从小到大的,这就意味着当前数组下标元素是最小的,如果最小的都大于0,那就没有必要再继续遍历了
if(nums[i] > 0){
break;
}
if(i > 0 && nums[i] == nums[i - 1]){
continue;//如果当前元素和上一个元素相同,那就没有必要再来一次,这也是为了防止有重复的
}
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{
list.add(Arrays.asList(nums[i],nums[left],nums[right]));
//这里的两个while循环是为了祛除相同元素的,比如说[-3,0,0,3,3]这种的
while(left < right && nums[left] == nums[left + 1]){
left++;
}
while(left < right && nums[right] == nums[right - 1]){
right--;
}
left++;
right--;
}
}
}
return list;
}
}
四数之和
题目链接如下:
题目截屏如下:
四数之和和三数之和的主要区别就是在外面套了一层循环。当然这是主要的,还有就是一些细节的处理。
public class 四数之和 {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
for(int i = 0;i < nums.length - 3;i++){//如果说当前数组元素只剩三个那就没有必要再继续找了
if(i > 0 && nums[i] == nums[i - 1]){//保证元素不相同
continue;
}
for(int j = i + 1;j < nums.length - 2;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{
list.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--;
}
}
}
}
return list;
}
}