数组练习题:两数之和三数之和四数之和
Posted 一朵花花
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数组练习题:两数之和三数之和四数之和相关的知识,希望对你有一定的参考价值。
两数之和
题目:
暴力求解: 直接遍历数组,依次求和进行比较即可
代码实现:
public int[] twoSum(int[] nums, int target){
for (int i = 0; i < nums.length - 1; i++) {
for (int j = i + 1; j < nums.length; j++) {
if(nums[i] + nums[j] == target){
return new int[]{i,j};
}
}
}
return new int[0];
}
三数之和
题目:
思考分析:
排序 + 双指针:
- 先对数组进行排序 Arrays.sort
- 使用指针 i 遍历数组,再用 left 和 right分别指向 i+1 和 length-1
- 遍历时,当 nums[ i ] > 0时,跳出循环,最小的首元素>0,则不可能出现三数之和为0
- 去重:出现以下情况,均跳过该元素,否则可能出现重复组合
a) i > 0 且 nums[ i ] = nums[ i-1] 时
b) left < right 且 nums[ left ] = nums[ left -1 ]时
c) left < right 且 nums[ right ] = nums[ right + 1 ]时
画图理解:
代码实现:
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
if(nums == null){
return null;
}
List<List<Integer>> array = new ArrayList<List<Integer>>();
//先对数组进行排序
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){
if(nums[i]+nums[left]+nums[right]==0){
array.add(Arrays.asList(nums[i],nums[left],nums[right]));
left++;
right--;
while(left < right && nums[left] == nums[left-1]){
left++;
}
while(left < right && nums[right] == nums[right+1]){
right--;
}
}
else if(nums[i]+nums[left]+nums[right] > 0){
right--;
}
else{
left++;
}
}
}
return array;
}
}
四数之和
题目:
思考分析:
和三数之和类似,只不过多了一层循环,且比较的对象变成了 target,这里不过多分析了,直接上代码
代码实现:
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> array = new ArrayList<List<Integer>>();
//数组排序
Arrays.sort(nums);
int n = nums.length;
for(int i = 0;i < n-3;i++){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
if(nums[i] + nums[i+1] + nums[i+2] + nums[i+3] > target){
break;
}
if(nums[i] + nums[n-3] + nums[n-2] + nums[n-1] < target){
continue;
}
for(int k = i + 1;k < n-2;k++){
if(k > i+1 && nums[k] == nums[k-1]){
continue;
}
if(nums[i] + nums[k] + nums[k+1] + nums[k+2] > target){
break;
}
if(nums[k] + nums[i] + nums[n-2] + nums[n-1] < target){
continue;
}
int left = k + 1;
int right = n - 1;
while(left < right){
int sum = nums[i] + nums[k] + nums[left] + nums[right];
if(sum == target){
array.add(Arrays.asList(nums[i],nums[k],nums[left],nums[right]));
while(left < right && nums[left] == nums[left+1]){
left++;
}
left++;
while(left < right && nums[right] == nums[right-1]){
right--;
}
right--;
}
else if(sum > target){
right--;
}
else{
left++;
}
}
}
}
return array;
}
}
最接近的三数之和
题目:
思考分析:
- 先对数组进行排序
- 使用 i 遍历数组
- 定义 left,right 分别指向 第二个元素和尾元素下标
- 依次求和 sum,sum 与 target 做差,比较大小
- 定义一个 ret,存放一个很大的数,每次做差后,将 ret 和 (sum 和 target 差) 的最小值赋值给 ret
- 最终返回 ret
代码实现:
class Solution {
public int threeSumClosest(int[] nums, int target) {
int ret = 1000;
Arrays.sort(nums);
for(int i = 0;i < nums.length-2;i++){
int left = i+1;
int right = nums.length-1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
if(Math.abs(sum-target) < Math.abs(ret-target)){
ret = sum;
}
if(sum > target){
right--;
}
else if(sum < target){
left++;
}
else{
return target;
}
}
}
return ret;
}
}
补充
(1).Math.abs
Math.abs(x)=|x|,x是什么类型,返回的便是什么类型
例:Math.abs( ),若括号里为 int 类型,则返回值是 int 类型的绝对值
(2).Arrays.asList
该方法是将数组转化成List集合的方法,返回由指定数组支持的固定大小的列表
详情可参考:在线文档
以上是关于数组练习题:两数之和三数之和四数之和的主要内容,如果未能解决你的问题,请参考以下文章