The beauty of programming 2.3 notes: Find and post "Water King"

Source: Internet
Author: User

Programming beauty 2.3:

Tango is a pilot project of Microsoft Asia Research Institute. Employees and interns of the institute like to communicate with tango. Legend has it that Tango has a big "Water King" who not only likes to post, but also replies to every post sent by other IDs. It is widely reported that the number of posts by the "Water King" has exceeded half of the total number of posts. If you have a list of all posts (including replies) on the previous Forum, and the ID of the post author is also in the table, can you quickly find the legendary Tango Water King?

How should we think about this problem during the interview? One of the major gains of reading SiCp is to learn abstraction. Aristocratic entertainment city

Abstraction

Abstraction is to extract useful and essential features from a problem and then express the problem with a model that is concise but contains the same information. After a complex problem is abstracted, it may become a simple problem or a previously encountered problem. Of course, it may still be a complicated problem. No matter which result is obtained after abstraction, looking at the problem after abstraction is more likely to come up with a solution than simply looking at the original question.

Abstract This question: Give you an array with more than half of the numbers in it. Your task is to find this number.

For processing numeric arrays, it is easy to think of sorting or hashing. Set these methods to the problem and you will get:

  1. After sorting, the median is output directly;
  2. Create a large hash table (the numeric value is its subscript in the hash table), traverse the array once, and place all the numbers in the hash table. In this process, if you find that the number of collisions exceeds half, you can find them.

This is the benefit of abstracting the problem-Easy knowledge migration.

Analysis and answer

The most direct method is to sort all the numbers in the array and scan them again to count the number of occurrences of each number. If a number appears more than half the number, the number is output. Obviously, the time complexity of this algorithm is O (n * log2n + n ).

In fact, if the array is already ordered, the number in the middle of the array must be the required number, so scanning is not required. The time complexity of the algorithm is O (n * log2n + 1 ). Can it be simplified?

We can see that the algorithm is mainly used for sorting. Can we skip the sorting step? In this case, if two different numbers (excluding the highest frequency) are deleted each time, the original highest frequency is more than 50% in the remaining number, repeat this process, and the rest will be the same number, that is, the highest frequency. This algorithm avoids sorting. the time complexity is only O (n ).

The Code is as follows:

# Include "stdio. H "int findfloodking (INT num [], int N) {int I; int candidate = 0; int COUNT = 0; for (I = 0; I <N; I ++) {If (COUNT = 0) {candidate = num [I]; Count = 1; printf ("% d candidate = % d \ n", I, candidate);} else {If (Candidate = num [I]) {count ++; printf ("% d candidate % d = num [I] % d, count auto increment: % d \ n ", I, candidate, num [I], count);} else {count --; printf (" % d candidate % d! = Num [I] % d, Count: % d \ n ", I, candidate, num [I], count) ;}} return candidate ;} int main () {int I, n, RS; int arr [] = {9,11, 11,13, 11,11, 11,18, 19,11, 11,20, 11}; n = sizeof (ARR) /sizeof (INT); RS = findfloodking (ARR, n); printf ("% d", RS );}

The program runs as follows:

0 candidate = 91 candidate 9! = Num [I] 11, count is reduced from 02 candidate = 113 candidate 11! = Num [I] 13, count is reduced to 04 candidate = 115 candidate 11 = num [I] 11, count is increased to 26 candidate 11 = num [I] 11, increase count to 37 candidate 11! = Num [I] 18, count is reduced from 28 candidate 11! = Num [I] 19, count is reduced to 19 candidate 11 = num [I] 11, count is increased to 210 candidate 11 = num [I] 11, count is increased to 311 candidate 11! = Num [I] 20, count is reduced to 212 candidate 11 = num [I] 11, count is increased to 311
  1. First, candidate equals num [1], candidate = 9
  2. Candidate (9 )! = Num [2] (11), so both 9 and 11 are discarded, and candidate = num [3] (11) is reset)
  3. Repeat this step to discard different records, and use count to record the accumulative count if the same number is met. The goal is to discard as many pairs of numbers as possible, and the last thing left is the "Number of water ".

In this topic, there is a common idea in computer science, that is, how to turn a problem into a number of smaller problems. Grouping, recursion, and greedy are all based on this idea. In the conversion process, small problems are essentially the same as the original problems. In this way, we can convert small problems into smaller problems in the same way. Therefore, the conversion process is very important. Like the above question, we ensure that the solution of the problem is still of the same nature as the original problem: the number of times that the ID of the Water King has exceeded half in the ID list. The higher the computing efficiency of the conversion itself, the faster the problem scale after conversion, the lower the time complexity of the overall algorithm.

Feature Utilization

Feature utilization is to customize a solution based on the characteristics of the problem. Generally, this special solution is optimal. To use this idea, you need to first find the characteristics of the problem, then think about what causes the emergence of the characteristics, and think about how to use the characteristics. Finally, if you can get an idea, you can customize a solution for the problem.

In "Searching for water Kings", that is, the above-mentioned problem is characterized by more than half of the occurrences of a number. Not inspired by the reason why more than half of the number of occurrences occurs. However, from the perspective of using this feature, we will be inspired by the fact that this number appears more times than the total number of remaining numbers. The number of occurrences is reduced, and the rest is the number of occurrences more than half. For example, 5, and 5 appear more than the total number of other numbers. In statistics, if 5 appears, the number of occurrences is increased by 1. If 5 does not appear, the number of occurrences is reduced by 1. The number of occurrences changes as follows, 1. This process is expressed as follows: if the next number is the same as 5, the number of occurrences increases by 1; otherwise, the number decreases by 1.

A more general description is: if the next number is the same as the previous one, the number of occurrences increases by 1. Otherwise, the number decreases by 1. In this case, no matter whether you know in advance that 5 is the most frequently seen, you will find that 5 is the number left at the end of the statistics. If you change the order of seven numbers to verify this general idea, you will find that this idea is correct. Turn this idea into code to get the optimal solution for this question.

Included functions:

Type Find(Type* ID, int N){    Type candidate;    int nTimes, i;    for(i = nTimes = 0; i < N; i++)    {        if(nTimes == 0)        {             candidate = ID[i], nTimes = 1;        }        else        {            if(candidate == ID[i])                nTimes++;            else                nTimes--;        }    }    return candidate;}
Scaling Problems

With the development of Tango, the Administrator found that "Super Water King" was gone. Statistics show that there are 3 posts with many IDs, and the number of posts exceeds 1/4 of the total number of posts n. Can you quickly find their IDs in the post ID list?

Refer to the above solution for the following ideas:

If you delete four different IDs (whether or not they contain more than 1/4 of the total number of posts, the proportion of IDs with the original posting ratio greater than 1/4 is still greater than 1/4. By repeating this process, you can reduce the total number of IDs in the ID List (converted to a smaller question) to get the answer to the question.

Void find (type * ID, int N, type candidate [3]) {type id_null; // defines a nonexistent ID int ntimes [3], I; ntimes [0] = ntimes [1] = ntimes [2] = 0; candidate [0] = candidate [1] = candidate [2] = id_null; for (I = 0; I <n; I ++) {If (ID [I] = candidate [0]) {ntimes [0] ++ ;} else if (ID [I] = candidate [1]) {ntimes [1] ++;} else if (ID [I] = candidate [2]) {ntimes [2] ++;} else if (ntimes [0] = 0) {ntimes [0] = 1; candidate [0] = ID [I];} else if (ntimes [1] = 0) {ntimes [1] = 1; candidate [1] = ID [I];} else if (ntimes [2] = 0) {ntimes [2] = 1; candidate [2] = ID [I];} else {ntimes [0] --; ntimes [1] --; ntimes [2] -- ;}} return ;}

The beauty of programming 2.3 notes: Find and post "Water King"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.