LeetCode Sum Question

Question 1.两个数求和问题,找出求和等于target的数对,只有一对。

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, and you may not use the same element twice.

Example:

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

Because nums[0] + nums[1] = 7 + 2 = 9,
return [0, 1].

Solution 1、直接采用双循环来暴力求解,但是问题是时间复杂度高。

Solution 2、对数组先进行排序,然后根据target-nums[i]求得补数,然后在数组中查找补数是否存在,该方法的时间复杂度是:

(排序)O(NlogN) + (遍历并查找)O(NlogN),所以总的复杂度是O(NlogN)。

Solution 3、采用HashMap,时间复杂度是O(N)

#define SIZE 100000

int hash(int key) {
    int r = key % SIZE;
    return r < 0 ? r + SIZE : r;
}

void insert(int *keys, int *values, int key, int value) {
    int index = hash(key);
    while (values[index]) {
        index++;
        index %= SIZE;
    }
    keys[index] = key;
    values[index] = value;
}

int search(int *keys, int *values, int key) {
    int index = hash(key);
    while (values[index]) {
        if (keys[index] == key) {
            return values[index];
        }
        index++;
        index %= SIZE;
    }
    return 0;
}

int* twoSum(int* nums, int numsSize, int target) {
    int keys[SIZE];
    int values[SIZE] = {0};
    for (int i = 0; i < numsSize; i++) {
        int complements = target - nums[i];
        int index = search(keys, values, complements);
        if (index) {
            int *indices = (int *) malloc(sizeof(int) * 2);
            indices[0] = --index;
            indices[1] = i;
            return indices;
        }
        insert(keys, values, nums[i], i + 1);
    }
    return NULL;
}

Question 2、三数求和的问题。

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

Solution 1、暴力求解,时间复杂度O(N^3)

Solution 2、采取定一个数或者两个数,这里我们假定我们每次取定三个数中的第一个数。然后用两个指针p,q指定首尾,然后往中间走,采取一个夹逼的办法实现。时间复杂度是O(N^2)

class Solution {   
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result= new ArrayList<List<Integer>>();
        Arrays.sort(nums);
        int p,q,Balance,i,sum;
        for(i = 0;i < nums.length-2;i++)
        {
            p = i;
            Balance = i+1;
            q = nums.length-1;  
            while(q > Balance)
            {
                sum = nums[p] + nums[Balance] + nums[q];
                //小了
                if(sum < 0)
                    Balance++;
                //大了
                else if(sum > 0)
                    q--;
                else
                {
                        List<Integer> Temp = new ArrayList<Integer>();
                        Temp.add(nums[p]);
                        Temp.add(nums[Balance]);
                        Temp.add(nums[q]);
                        result.add(Temp);
                        //剪枝
                        while(nums[Balance+1] == nums[Balance] && Balance < q && Balance < nums.length-2)
                            Balance++;
                        while(nums[q-1] == nums[q] && Balance < q && q > 1)
                            q--;
                        Balance++;
                        q--;
                }
            }//while
            while(nums[i+1] == nums[i] && i < nums.length-2)
                i++;
            
        }//for
        return result;
    }
}

Question 3、找最接近给定Target的三个数。

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Given array nums = [-1, 2, 1, -4], and target = 1.

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Solution 1、采用双指针的办法,设置一个上下边界,每次定一个数,然后设置两个指针从两头开始遍历,不停的进行边界的修改,最后比较上下边界和target的差距谁小就返回谁。

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int p,B,q;
        int UpBoard=10000;
        int DownBoard = -10000;
        int sum;
        for(int i = 0;i < nums.length-2;i++)
        {
            p = i;
            B = p+1;
            q = nums.length-1;
            while(B+1 <= q)
            {
                sum = nums[p] + nums[B] + nums[q];
                if(sum == target)
                    return target;
                if(sum > target)
                    q--;
                if(sum <UpBoard && sum >=target)
                    UpBoard = sum;                
                if(sum < target)
                    B++;
                if(sum >  DownBoard && sum < target)
                    DownBoard = sum;
            }
        }//for  
        int dis;
        dis = UpBoard - target;
        if(dis < target-DownBoard)
            return UpBoard;
        else
            return DownBoard;
    }   
}

Quesiont 4、4个数查找和等于target的所有数对。

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

The solution set must not contain duplicate quadruplets.

Example:

Given array nums = [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]
]

Solution:和上面的差不多,只是要多重循环,我们可以定前两个数,A,B,然后设置两个指针p,q,从首尾来夹逼。

Solution
class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        int i,j;
        int p1,p2,mid,q;
        int sum;
        int tempSum;
        for(i = 0;i < nums.length;i++)
        {
            for(j = i+1;j < nums.length;j++)
            {
                p1 = i;
                p2 = j;
                mid = p2 + 1;
                q = nums.length-1;
                tempSum = nums[p1] + nums[p2];
                while(mid < q)
                {
                    sum = tempSum + nums[mid] + nums[q];
                    if(sum  == target)
                    {
                        List<Integer> Temp = new ArrayList<Integer>();
                        Temp.add(nums[p1]);
                        Temp.add(nums[p2]);
                        Temp.add(nums[mid]);
                        Temp.add(nums[q]);
                        result.add(Temp);
                        while(mid < q && mid < nums.length-2 &&  nums[mid+1] == nums[mid])
                            mid++;
                        while(mid < q && q > 1 && nums[q-1] == nums[q])
                            q--;
                        q--;
                        mid++;
                    }
                    else if(sum > target)
                        q--;
                    else
                        mid++;
                }//while
                while(j < nums.length-1 && nums[j+1] == nums[j])
                    j++;
            }
            while(i < nums.length-1 && nums[i+1] == nums[i])
                i++;
        }//for
        return result;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值