2sum,3sum and 和为s的连续正数序列

2sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution.

Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
1.首先想到的是O(n^2)的解法,固定一个数,然后看它与后面数的加和是否等于目标值。
2.更好的解法是先对数组进行排序,然后用两个指针,一个从头开始,一个从尾开始,判断两个指针指向的和是否等于目标值,相等输出,如果大于目标值,尾指针前移,如果小于目标值,头指针后移。
3.在leetcode上遇到的难点是如何找到和为target的两个数在原数组中的位置?
我的代码如下:

public int[] twoSum(int[] nums, int target) {
        int[] original = new int[nums.length];//原始数组
        for(int i=0;i<original.length;i++){
            original[i] = nums[i];
        }
        Arrays.sort(nums);
        int[] result = new int[2];
        int low = 0;
        int high = nums.length-1;
        while(low<high){
            int sum = nums[low]+nums[high];
            if(sum==target){
                //下面是为了找nums[low],nums[high]在原数组中的位置
                int small = 0;
                int big = original.length-1;
                while(small<big&&original[small]!=nums[low])
                    small++;
                result[0] = small;
                small = 0;
                while(big>small&&original[big]!=nums[high])
                    big--;
                result[1] = big;
                break;


            }else if(sum<target){
                low++;
            }else{
                high--;
            }
        }

        return result;

    }

3sum

3sum的问题是在数组中找到3个和为0的数,3sum的解法可以固定一个数a,然后对其后面的数求2sum=-a,3sum问题的关键在于如何去重?比如数组{-1,0,1,2,-1,-4}中有两个-1,结果应该是[[-1,0,1],[-1,-1,2]]

public List<List<Integer>> threeSum(int[] nums){
        List<List<Integer>> resultList = new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        int n = nums.length;
        for(int i=0;i<nums.length-2;i++){
            int begin = i+1;
            int end = n-1;
            while(begin<end){
                int sum = nums[begin]+nums[end];
                if(sum==-nums[i]){
                    List<Integer> singleList = new ArrayList<Integer>();
                    singleList.add(nums[i]);
                    singleList.add(nums[begin]);
                    singleList.add(nums[end]);
                    if(!resultList.contains(singleList)) //去重
                        resultList.add(singleList);
                    end--;
                    begin++;
                }else if(sum<-nums[i]){
                    begin++;
                }else{
                    end--;
                }
            }
        }
        return resultList;
    }

ps:这段代码在牛客网提交通过了,但是在leetcode上不知为何运行超时

和为s的连续正数序列

问题描述:输入一个整数s,打印出所有和s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5,4~6,7~8
思路:用两个数small和big分别表示数组的最小值和最大值,首先把small初始化为1,big初始化为2,如果small到big的序列大于s,从序列中去除较小的值,也就是增大small的值,如果如果small到big的序列小于s,就增大big的值。
代码:

public class Solution {

    /**
     * @param args
     */
      ArrayList<ArrayList<Integer>> resultList =new  ArrayList<ArrayList<Integer>>();
     public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {


           int small = 1; //序列的最小数
           int big = 2;  //序列的最大数
           int middle = (sum+1)/2; //序列的中间数
           int curSum = small + big; //当前和
           while(small<middle){
               if(curSum==sum){
                   addToList(small,big);
               }
              while(curSum>sum&&small<middle){
                   curSum -= small;
                   small++;
                   if(curSum==sum){
                       addToList(small,big);
                   }
               }
              big++;
              curSum += big;
           }
           return resultList;
       }
      private void addToList(int small, int big) {
        ArrayList<Integer>  singleList = new  ArrayList<Integer>(); //存放一条结果的链表
        for(int i=small;i<=big;i++){
            singleList.add(i);
        }
        resultList.add(singleList);

    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值