AC series daily (two): the closest three and the number of

1 title

leetcode number 16 , given an array with a number of goals, identify which of the three numbers in the array, and the closest of the three to the number of the target number.
Here Insert Picture Description

2 violence

Traditionally a first-come, O (n3) of violence:

int temp = nums[0]+nums[1]+nums[2];
for(int i=0;i<nums.length;++i)
    for(int j=i+1;j<nums.length;++j)
        for(int k=j+1;k<nums.length;++k)
        {
            int temp1 = nums[i]+nums[j]+nums[k];
            if(Math.abs(temp-target) > Math.abs(temp1-target))
            {
                temp = temp1;
                if(temp == target)
                    return target;
            }
        }
return temp;

then. . . .
Here Insert Picture Description
Flattered, ah, actually gave a direct violence. . .

3 O (n2)

Well, I myself could not stand this kind of violence, engage in serious things, then three cycles of violence directly, each time adding three numbers and determine the distance of the target, if the target is a direct return, if not continued, However, ... O (n3) ah ...
in fact, this it can also be used on an article in the double pointer mentioned method, to sort the array, and then a fixed number, then the two pointers to the beginning and end of the tip, and then continue to intermediate approach.

Arrays.sort(nums);
int t1 = nums[0]+nums[1]+nums[2];
for(int i=0;i<nums.length-2;++i)
{
    int left = i+1;
    int right = nums.length-1;

    while(left < right)
    {
        int t2 = nums[i]+nums[left]+nums[right];
        if(t2 == target)
            return target;
        else if(t2 > target)
            --right;
        else 
            ++left;
        if(abs(t1-target) > abs(t2-target))
        {
            t1 = t2;
        }
    }
}
return t1;

First, sort the array, nums [i] is a fixed number, left and right two pointers to two, according to the calculated t2 = nums [i] + nums [left] + nums [right] Analyzing the relationship between target, it is larger than right pointer moves to the left, then moves to the right is smaller than the left pointer, the pointer until the two meet. Sorting requires O (n log n), two cycle requires O (n2), the overall time complexity is O (n2).
Here Insert Picture Description

4 impact 2ms

To see a bit of that first answer, 2ms, really fast, mostly handwritten fast row, and then for the inside of the loop with the maximum and minimum pruning.

4.1 Handwriting fast row

To search a bit Arrays.sort () algorithm, which is a combination of several algorithms:
Here Insert Picture Description
( Source )

Only when the length of the array is less than 286 not less than 47, it will be called quick sort, thus directly handwritten here a fast discharge, regardless of the length of the fast row number used directly.
(Principle is not to say, fast handwriting row or a little bit of difficulty ...)

public void qs(int [] nums,int l,int r)
{
    if(l < r-1)
    {
        int t = l;
        int ll = l+1;
        int rr = r-1;
        int temp;
        while(true)
        {
            while(t < rr && nums[t] < nums[rr])
                --rr;
            if(t < rr)
            {
                temp = nums[rr];
                nums[rr] = nums[t];
                nums[t] = temp;
                t = rr--;
            }
            else
                break;
            while(ll < t && nums[ll] < nums[t])
                ++ll;
            if(ll < t)
            {
                temp = nums[ll];
                nums[ll] = nums[t];
                nums[t] = temp;
                t = ll++;
            }
            else
                break;
        }
        qs(nums,l,t);
        qs(nums,t+1,r);
    }
}

Originally two while loop condition

while(ll < rr && ...)

Later, out of the bug, tune a bit and found a range wrong, changed two while:

while(t < rr && ...)
while(ll < t && ...)

4.2 maximum and minimum pruning

Pruning is to calculate the minimum number that is fixed, and also determines the size of the smallest target number of two, and if this minimum value is greater than the target, then the result may be the minimum value, however, can not be other values, since the minimum value, and larger than the target, then added to other values, then only further away from the target value, it is determined directly after the minimum break.

Maximum pruning is similar, with two numbers is calculated and the maximum size of the target is determined that the number of fixed, if less than the target value, the result may be the maximum value, other values ​​could not be determined after also a direct break.

int left = i+1;
int right = nums.length-1;
if(left < right)
{
    int min = nums[i] + nums[left] + nums[left+1];
    if(min > target)
    {
        if(abs(min - target) < abs(t1 - target))
            t1 = min;
        continue;
    }
}

int max = nums[i] + nums[right] + nums[right-1];
if(max < target)
{
    if(abs(max - target) < abs(t1 - target))
        t1 = max;
    continue;
}

4.3 Oh ...

Here Insert Picture Description
A word, fun.

5 Source

github
code Clouds

Published 47 original articles · won praise 4 · Views 4127

Guess you like

Origin blog.csdn.net/qq_27525611/article/details/104078031