再练习数组算法题前回顾下数组这个数据结构。
数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
题目描述:
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
这是一个经典 数组题:
解题方法:
-
首先对数组进行排序,排序后固定一个数 nums[i],再使用左右指针指向 nums[i]后面的两端,数字分别为 nums[left] 和 nums[right],计算三个数的和 sum判断是否满足为 0,满足则添加进结果集
-
因为进行了排序,数组都是递增的,如果 nums[i]大于 0,则三数之和必然无法等于 0,结束循环
-
如果 nums[i] == nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过
-
计算 sum = nums[i] + nums[left] + nums[right];
-
当 sum=0 时,nums[L]== nums[L+1] 则会导致结果重复,应该跳过,left++
-
当 sum = 0 时,nums[R] = nums[R−1] 则会导致结果重复,应该跳过,right−−
-
时间复杂度:O(n^2),n为数组长度
private static List<List> threeSum(int[] nums){ List<List> rest = new ArrayList<>(); if(nums == null || nums.length <3){ return rest; } Arrays.sort(nums); for (int i=0;i<nums.length-2;i++){ 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){ rest.add(Arrays.asList(nums[i],nums[left],nums[right])); while(left < right && nums[left] == nums[left+1]){ left++; } while(left < right && nums[right] == nums[right-1]){ right--; } left ++; right --; }else if(sum <0){ left ++; }else{ right --; } } } return rest;}