Thinking about the AHA algorithm and some code implementation

Source: Internet
Author: User

"A problem that seems difficult may have a simple, unexpected solution"

-A seemingly hard-to-solve problem may be hidden behind a simple and unexpected solution.

 

Three examples:

 

1. Input a continuous file. The file stores 4,000,000,000 32-bit integers in any order. Please find an integer that is not in this sequence (Why must there be at least one missing data ).

Q1 How do you solve this problem if you have enough memory?

Q2. How do you solve this problem if you only provide some external files that can be used but only a few hundred bytes of memory.

 

2. Assume that you enter a string with a length of N, Please rotate the string at the position I. For example, n = 8, I = 3, and the array is abcdefgh. After rotation, it becomes defghabc. You can use O (N)AlgorithmIs O (1) space used to solve this problem?

 

3. Provide an English dictionary containing words. Find all the anagrams, such as pots, stop, and tops. Because the letters that make up words are the same, they are only arranged differently.

 

Question 1.

For the first question, our data is 4billion, and 4,294,967,296 of 32bit data must be lost. To solve this problem, if there is a large amount of memory, you can use the Count sorting method assisted by bitmap to find the missing number. The memory used is about 536 MB.

The second problem is how to solve the problem if there are only several hundred bytes of memory and some continuous files.

I have been thinking about this algorithm for a long time, and I have read some materials to understand it.

The binary principle is as follows: (The problem is simplified. We assume that there are only 3-bit numbers. In this case, our range is 0-7. For example, the missing number is 3)

The first step is to traverse this file and use the highest bit value as the basis for binary.

For example, our data is (unordered and 3 is lost)

6 (110)

2 (010)

0 (000)

1 (001)

4 (100)

7 (111)

5 (101)

The result of the second step is file1 (the highest bit is 1, the range is 100-111): 6 4 7 5 file2: 2 0 1. (the range is 000-011)

When splitting, if the number of numbers in the file is smaller than the expected number, there should be four here, so we think there is data loss. So there is a loss of digits in the location in file2.

 

The second step is to continue searching for lost files. However, this time the second bit is used for binary classification.

In file2, the content is divided

File3 :( 2) file4: 0 1

At this time, we found that numbers are missing in the range of file3 (010-011. In this case, the missing number is 3.

The most important aspect of this algorithm is that it is not a binary search defined based on normal sorting. We cannot find the use of sorting In the algorithm, but can find the missing number.

This reminds me of counting sorting. Counting sorting records the number of each element value in a range. This topic is to count the number of elements in a certain range and then subdivide them down.

 

Question 2:

This programming topic is actually quite classic and also mentioned in the crack code interview. General idea

 

First, store a [0] in the Temporary Variable temp, and then sequentially store a [I]-> A [0] a [2I]-> A [I], of course, every time n * I is used, the Moore operation must be performed on the array size and size. Until the loop goes to a [0].

If a [1] is not processed at last, put a [1] into temp to repeat the above process. Math can prove that the number of times used cyclically is gcd (size, I). The size is N in the description, and I is rotate from the I element.

CodeWrite as follows:

[CPP]
View plaincopyprint?
  1. # Include <stdio. h>
  2. Template<TypenameT>
  3. VoidSwap (T & A, T & B)
  4. {
  5. T c =;
  6. A = B;
  7. B = C;
  8. }
  9. IntGcd (IntM,IntN)
  10. {
  11. If(N> m)
  12. {
  13. Swap (m, n );
  14. }
  15. IntR;
  16. While(N)
  17. {
  18. R = m % N;
  19. M = N;
  20. N = R;
  21. }
  22. ReturnM;
  23. }
  24. Template<TypenameT>
  25. VoidRotatearray (T vdata [],IntNsizearray,IntIrot)
  26. {
  27. IntNshift = gcd (nsizearray, irot );
  28. For(IntI = 0; I <nshift; I ++)
  29. {
  30. T TMP = vdata [I];
  31. IntCur = I, NXT;
  32. IntJ = 0;
  33. While(1)
  34. {
  35. NXT = (J + 1) * irot + I) % nsizearray;
  36. Cur = (j) * irot + I) % nsizearray;
  37. If(NXT = I)
  38. {
  39. Break;
  40. }
  41. Vdata [cur] = vdata [NXT];
  42. J ++;
  43. }
  44. Vdata [cur] = TMP;
  45. }
  46. }
  47. IntMain ()
  48. {
  49. CharS [10] ="Abcdefghi";
  50. Rotatearray (S, 9, 5 );
  51. Printf (s );
  52. Return0;
  53. }
 
 

Solution 2:

If the array to be rotated is X, the array can be divided into xy. A is the first I element, And I indicates that the element is rotated.

For example, if I is 3, then x = ABC y = defg. In this case, the essence of the problem can be understood as converting XY into Yx through exchange.

Assume that the length of Y is longer than that of X, so it can be expressed as X (yl) (yr), and the length of YR is the same as that of X. Switch X and yr to get (yr) (yl) X. What we need to do is switch (yr) (yl) to (yl) (yr ). In this case, we can use recursive methods to solve the problem.

[CPP]
View plaincopyprint?
  1. Template<TypenameT>
  2. VoidRotatearray (T vdata [],IntF,IntM,IntT)
  3. {
  4. IntNL = m-F;
  5. IntNr = T-m + 1;
  6. IntI, J;
  7. If(NL> nr)
  8. {
  9. For(I = F, j = m; j <= T; I ++, J ++)
  10. {
  11. Swap (vdata [I], vdata [J]);
  12. }
  13. Rotatearray (vdata, F + nR, M, t );
  14. }
  15. Else If(NL <nr)
  16. {
  17. For(I = F, j = T-nl + 1; I <m; I ++, J ++)
  18. {
  19. Swap (vdata [I], vdata [J]);
  20. }
  21. Rotatearray (vdata, F, M, T-nl );
  22. }
  23. Else If(NL = nR)
  24. {
  25. For(I = F, j = T; I <j; I ++, j --)
  26. {
  27. Swap (vdata [I], vdata [J]);
  28. }
  29. }
  30. }

Solution 3.But this code does not really feel like aha, maybe it should be called ouch, right. The above method requires careful programming. In fact, there can be more aha algorithms.

To convert AB to Ba, you can perform the following operations: first, reverse (A), reverse (B), and finally reverse (AB ). Haha, does it feel like Aha.

 

Question 3:

This topic is my first thought of using a hash table to calculate a hash value for each string. However, I have not figured out how to map spot and pots to the same hash slot.

The idea provided by the author is actually similar.

1. sign each word

2. sort by signature.

The signature used by the author here is also a very simple method, that is, the re-arrangement of the letter order of a word. For example, if you select spot-> opst and the signature of pots is also opst, they will have the same ranking.

If I design the data structure, I will write it

 

Struct wordpair

{

Char strword [max_path];

Char strsigniture [max_path];

}

ProgramIn the first step, enter all the strings and obtain all signiture. Then, sort the strings by signature to obtain homogeneous words.

 

This gives me some tips on the hash method. If I sort the data first and then hash it, isn't it my solution ~

 

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.