LeetCode:. 2 reports two numbers together and problem-solving algorithm optimization ideas

Title connection: 2. adding two numbers

The meaning of problems

Difficulty of the subject labeled 中等as part of the difficulty of understanding, and a list of basic data structures required on the meaning of the questions.

Do not know the chain of children's shoes can look rough Baidu Encyclopedia pulls out a book or look at the data structure, a little plain language to explain the list is this: on-line and off-line .

Know your on-line off the assembly line, but do not know off the assembly line off the assembly line, they also do not know who their on-line yes.

This is a one-way linked list .

This question of the meaning of the questions is, the two numbers into a two-way linked list, where each node stores digit, and is the reverse storage, which is reversed saved.

Problem-solving ideas

First, let's think about different situations and the corresponding case:

  1. Chain length equal to two.

Input : (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output : (7 -> 0 -> 8)

  1. Two lists of unequal length.

Input : (2 -> 4) + (5 -> 6 -> 4)
Output : (7 -> 0 -> 5)

  1. Carry the presence of the highest level of the final result.

Input : (2 -> 4 -> 5) + (5 -> 6 -> 4)
Output : (7 -> 0 -> 0 -> 1)

The key problem-solving is: merge lists and ensure that carry the right .

Analog carry

First, we sum bit, and then to carry each bit processing, full 10proceeds 1.

Code:

    public class Solution
    {
        public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
        {
            ListNode first = null;
            ListNode current = null;
            IList<int> sums = new List<int>();
            int sum = 0;
            int res = 0;

            while (l1 != null || l2 != null)
            {
                sum = res;
                if (l1 != null)
                {
                    sum += l1.val;
                    l1 = l1.next;
                }

                if (l2 != null)
                {
                    sum += l2.val;
                    l2 = l2.next;
                }

                res = sum / 10;
                sum %= 10;
                sums.Add(sum);
            }

            if(res > 0) sums.Add(res);

            if(sums.Any()) first = new ListNode(sums[0]);

            current = first;

            for (int i = 1; i < sums.Count; i++)
            {
                current.next = new ListNode(sums[i]);
                current = current.next;
            }

            return first;
        }
    }

When execution : 252 ms, beat the 13.33% of all users in C # to submit
memory consumption : 26.7 MB

This takes a bit miserable, near the bottom of. It also shows that there is still much room for optimization.

Constant optimization

Above we use when cycling to IListthe Count, where we can store it up in advance.

code show as below:

    public class Solution
    {
        public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
        {
            ListNode first = null;
            ListNode current = null;
            IList<int> sums = new List<int>();
            int sum = 0;
            int res = 0;
            int count = 0;

            while (l1 != null || l2 != null)
            {
                sum = res;
                if (l1 != null)
                {
                    sum += l1.val;
                    l1 = l1.next;
                }

                if (l2 != null)
                {
                    sum += l2.val;
                    l2 = l2.next;
                }

                res = sum / 10;
                sum %= 10;
                sums.Add(sum);
            }

            if (res > 0) sums.Add(res);

            count = sums.Count;

            if (count > 0) first = new ListNode(sums[0]);

            current = first;

            for (int i = 1; i < count; i++)
            {
                current.next = new ListNode(sums[i]);
                current = current.next;
            }

            return first;
        }
    }

When execution : 164 ms, beat the 85.62% of all users in C # to submit
memory consumption : 26.8 MB

Just replace a variable, it optimizes the execution by nearly 100ms! This 100ms to more than 70%submission.

Front and nearly 15%indicating that there is room for optimization.

Optimization of the number of cycles

Above algorithm, according to the Big O notation to calculate the complexity of the case, its complexity is: O(max(l1.Length, l2.Length))then what is streamlined O(n), that the extent of unit weight cycle.

But the real complexity is (also the estimated number of operations within the cycle is not considered to come here just forget loop): 2 * max(l1.Length, l2.Length) + 1. Because here actually uses two loops. Then we can use this expression of the complexity of the multiple : 2to remove, that is only a re-circulation.

code show as below:

    public class Solution
    {
        public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
        {
            ListNode first = null;
            ListNode current = null;
            int sum = 0;
            int res = 0;

            while (l1 != null || l2 != null)
            {
                sum = res;
                if (l1 != null)
                {
                    sum += l1.val;
                    l1 = l1.next;
                }

                if (l2 != null)
                {
                    sum += l2.val;
                    l2 = l2.next;
                }

                res = sum / 10;
                sum %= 10;

                if (current == null)
                {
                    first = new ListNode(sum);
                    current = first;
                }
                else
                {
                    current.next = new ListNode(sum);
                    current = current.next;
                }
            }

            if (res > 0) current.next = new ListNode(res);

            return first;
        }
    }

When execution : 136 ms, beat the 98.85% of all users in C # to submit
memory consumption : 26.5 MB

After we removed a heavy fall cycle, performed with the optimization of 20multi-ms (why is not optimized for nearly half the time?), Which is 20more than ms than it has 13%submitted.

Leetcode sentenced to ponder the question of time-consuming

In the subject of two successive road have no way to reach the best (at least the first 1%case), and if the feather wrote here today, specifically to see a bit time-consuming shortest code ( 104MS), submitted directly after copying down, the results show It is 248ms! ??

After submitting the results again show that 160ms! ??

The same code, the range of plus or minus a bit too big! If the feather can not help but think about the LeetCodehow judgments core problem is the timing of. This floating range has been reached can destroy ranking fairness degree, maybe some people will think that if the feather alarmist, exaggerated.

The fact is: it has been destroyed to the extent of the fair! ! ! This class online and automatically running code input cases in fact has emerged very early on the results than the system in the informatics contest and ACM Collegiate Programming Contest commonly referred to as OJ(Online Judge System)online judge. In the competition field, the gap reached 160what ms mean? It means that both teams players at the same time or even a little bit later point submit code, and ultimately who rank in the top have to listen to fate .

Despite competition standpoint, such a large floating ranking, to a certain extent, has been unable to evaluate objectively the merits of the similar time complexity of the algorithm. Algorithm ranked first run it again there may be routed to the end.

But the idea of optimization algorithm can still continue, stop line and code to optimize more than ~ (really want to own a realization OJof!)

Guess you like

Origin www.cnblogs.com/By-ruoyu/p/11323293.html
Recommended