数组—— 2 sum, 3 sum, 3 sum closed, 4Sum.

来源:互联网 发布:网络新媒体专业课程 编辑:程序博客网 时间:2024/06/07 02:57

题目一:2 sum      找两数之和为target的下标。

hashmap 当哈希表中不存在当前i的数字target-numbers[i]时,将(numbers[i],i)put入表;找到则返回。

import java.util.*;public class Solution {    public int[] twoSum(int[] numbers, int target) {        int[] index=new int[2];        if(numbers == null||numbers.length<2)            return index;        Map<Integer,Integer> map=new HashMap();        map.put(numbers[0],0);        for(int i=1;i<numbers.length;i++)            {            if(map.containsKey(target-numbers[i]))                {                index[0]=map.get(target-numbers[i])+1;                index[1]=i+1;            }            else                {                map.put(numbers[i],i);            }        }        return index;    }}

若题目要求为保存数值,也可排序后使用双下标从两端查找。

 public int[] twoSum(int[] numbers, int target) {        int[] index=new int[2];        if(numbers == null||numbers.length<2)            return index;               Arrays.sort(numbers);           int left=0;        int right=numbers.length-1;        while(left<right)            {            if(numbers[left]+numbers[right] == target)                {                index[0]=numbers[left];                index[1]=numbers[right];                break;            }            else if(numbers[left]+numbers[right] < target)                {                left++;            }else                {                right--;            }        }        return index;    }


题目二:3 sum   数组中是否存在三个数a,b,c使得a+b+c = 0?

并且需要满足的条件为:

  • 1. triplet (a,b,c) 不能降序排列. (ie,a ≤ b ≤ c),   
  • 2. ArrayList<ArrayList<Integer>>中不能存放重复的triplet.

For example, given array S = {-1 0 1 2 -1 -4},    A solution set is:    (-1, 0, 1)    (-1, -1, 2)
题解:从所需满足的条件判断,应该先对数组num排序,然后将3 Sum分解为【1 sum+2 sum】,即固定一个数字,另外的两个数组按照2 sum的解法,并且所要储存的是值,所2 sum可以采用两个下标的方法。

public class Solution {    public ArrayList<ArrayList<Integer>> threeSum(int[] num) {        ArrayList<ArrayList<Integer>> array=new ArrayList();        if(num == null||num.length<3)            return array;                ArrayList<Integer> list=new ArrayList();        Arrays.sort(num);//排序;        for(int i=0;i<num.length-2;i++)            {            if(i>0&&num[i] == num[i-1])//不能有重复的triplet;                continue;           int left=i+1;            int right=num.length-1;            while(left<right)//防止越界;                {            int sum=num[i]+num[left]+num[right];            if(sum == 0)                {                list.add(num[i]);                list.add(num[left]);                list.add(num[right]);                array.add(list);                list=new ArrayList();                //left和right都要移位。                left++;                while(left<right&&num[left] == num[left-1])//防止有连续重复的值;                    {                    left++;                }                right--;                while(right>left&&num[right] == num[right+1])//防止有连续重复的值;                    {                    right--;                }            }            else if(sum<0)                left++;                else                right--;            }        }        return array;    }

题目三:3 sum closed


错误分析:

closed为数组中三数之和中最接近target的,那么初始化closed时随便找三个数组元素求和就好了,如closed =num[0]+num[]1+num[2] is correct!

import java.util.*;public class Solution {    public int threeSumClosest(int[] num, int target) {        if(num == null||num.length<3)            return 0;                Arrays.sort(num);        int closed=Integer.MAX_VALUE;//closed =num[0]+num[]1+num[2] is correct!         // System.out.println(Math.abs(Integer.MAX_VALUE-(-1)));得:-2147483648。补码的原因。        for(int i=0;i<num.length-2;i++)            {            if(i>0&&num[i] == num[i-1])                continue;                        int left=i+1;            int right=num.length-1;            while(left<right)                {                int sum=num[i]+num[left]+num[right];                if(sum == target)                    {                   return target;                }                if(Math.abs(target-sum)<Math.abs(closed-target))                      {                      closed=sum;                   }                                if(sum<target)                    {                    left++;                 }else                    {                     right--;                }            }        }        return closed;    }}


题目四:4 Sum

题目描述

一个有n个整数的数组,是否存在四个元素a, b, c, d使得 a + b + c + d = target? 找出所有的满足条件的四个为一组的元素。

 注:

  • 1.quadruplet (a,b,c,d) 不能降序排列. (ie, a ≤ b ≤ c ≤ d), 
  • 2. ArrayList<ArrayList<Integer>>中不能存放重复的quadruplet.
例如:

   given array S = {1 0 -1 0 -2 2}, and target = 0.    A solution set is:    (-1,  0, 0, 1)    (-2, -1, 1, 2)    (-2,  0, 0, 2)
题解:
1.先对数组进行排序;
2.固定一个数num[i],对之后的数进行3 Sum;
总的时间复杂度为O(N^3)!
public ArrayList<ArrayList<Integer>> fourSum(int[] num, int target) {        ArrayList<ArrayList<Integer>> array=new ArrayList();        if(num == null||num.length<4)            return array;         ArrayList<Integer> list=new ArrayList();        Arrays.sort(num);        for(int i=0;i<num.length-3;i++)            {            if(i>0&&num[i] == num[i-1])                continue;//避免重复;            //3 Sum            for(int j=i+1;j<num.length-2;j++)                {                if(j>i+1&&num[j] == num [j-1])                    continue;//避免重复;                int left=j+1;                int right=num.length-1;                while(left<right)                    {                    int sum=num[i]+num[j]+num[left]+num[right];                    if(sum == target)                        {                         list.add(num[i]);                         list.add(num[j]);                         list.add(num[left]);                         list.add(num[right]);                        array.add(list);                        list=new ArrayList();                 //sum == target情况时,left++和right--操作不能遗漏,且两个都有必要!                    left++;                    while(left<right&&num[left] == num[left-1])//避免重复;                        left++;                    right--;                    while(left<right&&num[right] == num[right+1])//避免重复;                        right--;                    }                    else if(sum<target)                        {                        left++;                    }else                        {                        right--;                    }                }            }        }        return array;    }


0 0
原创粉丝点击