LeetCode 754 Reach a Number

The meaning of the question: The starting point is at the origin on the number axis. For the nth step, you can choose to move n units to the left or right to find the minimum number of steps to reach the target.

think:

At first, there was no idea. Since the data range directly covers the entire int type, bfs is definitely impossible;

Try being greedy, but there is no mathematical basis for that. It is easy to prove that the target has symmetry, so it does not consider the situation of jumping in the opposite direction (greedy idea), and keeps going to the right until it is close to the target;

Because the difference between the kth step and the k+1th step is 1, it can be considered that for a path of length 1, there is cost(1)=2;

So if the distance target is now d, is the answer 2*d?

It's easy to think of counterexamples, but the solution to this problem seems to be just one more jump and seeing which of the two 2d and 2d' is smaller.

I tried to hand in one, and the result was n=4 and it didn't work:

  • -1+2+3=4,years=3
  • 1+2-3+4=4,years=4

The difference is that in the first step, the answer is jump-back, so greed must be wrong.

It is easy to convert the original problem into a mathematical problem, an equation, put 1, 2, 3, ..., n and target in, and find the smallest n to make the equation hold.

I seem to have seen something similar in high school, but it is too old. Maybe the students in the math competition can find a solution soon.

Now consider the whole process:

  1. 0+1=1
  2. 1+2=3
  3. 3+3=6
  4. ...

 

  1. 0-1=-1
  2. -1+2=1
  3. 1+3=4√

We can find that finding the positive solution requires inverse operations at some steps, and the difference generated by one inverse operation is 2n compared to the positive operation, which means that we can correct the answer by subtracting some 2n from the greedy result. Since n is increasing (contains consecutive numbers), there is no need to consider the out-of-bounds problems caused by corrections and the problems of insufficient corrections.

Therefore, for the case where the difference between the result position and the target after greed is an even number, we can get a positive solution by modifying the operation symbol, and the number of steps does not need to be changed at this time;

For the case of odd numbers, it depends on the current value of n. What we want to do is to convert the current odd number into an even number. If the current value of n is an odd number, we only need to take one more step to get the above situation, that is, ans+ =1;

The current n is an even number, the parity of the difference between position and target cannot be changed. At this time, two more steps are required, that is, ans+=2;

Because we used a greedy strategy before, the default is that there is no other optimal solution for the shortest path to the target, which can probably prove the correctness of the above algorithm.

The following code part, but the final parity part is not made into the form of +1+2 for convenience and good looks, it is best to complete the code according to your own understanding:

class Solution {
public:
    int reachNumber(int target) {
        int ans = 0;
        if (target < 0) target *= -1;
        if (target == 0) return ans;
        int pos = 0;
        while(pos < target){
            ++ans;
            pos += ans;
        }//O(sqrt(n)), for more powerful data, please do solve the formula to get the answer
        if (pos > target){
            int delta = pos - target;
            if (delta % 2 == 1){
                if (ans % 2 == 0)
                    ++ans;
                else ans += 2;
            }
        }
        return ans;
    }
};

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326383674&siteId=291194637