image.png

解题思路

双指针 Map

  1. public List<List<Integer>> fourSum(int[] nums,int target){
  2. /*定义一个返回值*/
  3. List<List<Integer>> result=new ArrayList<>();
  4. /*当数组为null或元素小于4个时,直接返回*/
  5. if(nums==null||nums.length<4){
  6. return result;
  7. }
  8. /*对数组进行从小到大排序*/
  9. Arrays.sort(nums);
  10. /*数组长度*/
  11. int length=nums.length;
  12. /*定义4个指针k,i,j,h k从0开始遍历,i从k+1开始遍历,留下j和h,j指向i+1,h指向数组最大值*/
  13. for(int k=0;k<length-3;k++){
  14. /*当k的值与前面的值相等时忽略*/
  15. if(k>0&&nums[k]==nums[k-1]){
  16. continue;
  17. }
  18. /*获取当前最小值,如果最小值比目标值大,说明后面越来越大的值根本没戏*/
  19. int min1=nums[k]+nums[k+1]+nums[k+2]+nums[k+3];
  20. if(min1>target){
  21. break;
  22. }
  23. /*获取当前最大值,如果最大值比目标值小,说明后面越来越小的值根本没戏,忽略*/
  24. int max1=nums[k]+nums[length-1]+nums[length-2]+nums[length-3];
  25. if(max1<target){
  26. continue;
  27. }
  28. /*第二层循环i,初始值指向k+1*/
  29. for(int i=k+1;i<length-2;i++){
  30. /*当i的值与前面的值相等时忽略*/
  31. if(i>k+1&&nums[i]==nums[i-1]){
  32. continue;
  33. }
  34. /*定义指针j指向i+1*/
  35. int j=i+1;
  36. /*定义指针h指向数组末尾*/
  37. int h=length-1;
  38. /*获取当前最小值,如果最小值比目标值大,说明后面越来越大的值根本没戏,忽略*/
  39. int min=nums[k]+nums[i]+nums[j]+nums[j+1];
  40. if(min>target){
  41. continue;
  42. }
  43. /*获取当前最大值,如果最大值比目标值小,说明后面越来越小的值根本没戏,忽略*/
  44. int max=nums[k]+nums[i]+nums[h]+nums[h-1];
  45. if(max<target){
  46. continue;
  47. }
  48. /*开始j指针和h指针的表演,计算当前和,如果等于目标值,j++并去重,h--并去重,当当前和大于目标值时h--,当当前和小于目标值时j++*/
  49. while (j<h){
  50. int curr=nums[k]+nums[i]+nums[j]+nums[h];
  51. if(curr==target){
  52. result.add(Arrays.asList(nums[k],nums[i],nums[j],nums[h]));
  53. j++;
  54. while(j<h&&nums[j]==nums[j-1]){
  55. j++;
  56. }
  57. h--;
  58. while(j<h&&i<h&&nums[h]==nums[h+1]){
  59. h--;
  60. }
  61. }else if(curr>target){
  62. h--;
  63. }else {
  64. j++;
  65. }
  66. }
  67. }
  68. }
  69. return result;
  70. }