Algorithm Walkthrough 1: diamonds and stones

After what is the algorithm design, learning is learning algorithm design. With skilled craftsmen as an effective means of strong algorithms, it is training, daily or problems encountered in the work, is a training and take the initiative to brush the question, is another training.

Here's brush subject leetcode, leecode an algorithm can answer website address is: https://leetcode.com/ , not long ago the Chinese version, the address is: https://leetcode-cn.com/

This time, first to a topic:
Diamonds and stones

For this problem, a natural idea is to follow the meaning of the questions, that is, to determine the number of occurrences of the letter J in S. If you can determine the number of J appeared in a letter, that all the letters could judge - reusable routine came out.

Therefore, according to natural idea, the letter appears a number of J is judged as a standard work, "reuse" routine basis prior to the use of a small way mentioned several times, the number of each letter appears add up, the problem can be Get rid of.

However, the general nature of the idea, is not efficient algorithms.

This topic should not simply apply the "reuse" of routines to solve the problem, you need to think about a more efficient design.

To design a good algorithm, you might first design or choose an appropriate data structure. Knife cutting down trees, or artillery to fight mosquitoes, are inappropriate, but without arms bare hands Mines inappropriate. There is a routine, in order to solve a problem, first get a weapon out.

This article describes a basic algorithm design routines, designed to solve the problem of a particular data structure. This routine, everywhere. In order to design an algorithm to design a data structure. Data structure, that is, the organizational structure of the data, the organization must have its own characteristics.

For this problem, the use of this routine, that is, how to design a kind of data structure in order to make the letters J to quickly know the number of times it appears own (rather than one by one, paired with the letters S)?

According to the characteristics of S (only letters, case sensitive), can be designed such a data structure: an array, the array can cover the length of the value of all the letters, also in alphabetical index value as be able to find a location and the value of this position is the number of times the letter appeared.

If there is such an array, then to find out the number of occurrences of the letter J in the very simple to the letter of the value of the index, the number of times is the emergence of corresponding value.

Such an array, how to build up?

To 'z' value + 1 as a length of the array, plus 1 because the array index starts from 0, let 'z' is the index can find a location.

When the initial array, the value of each element is 0.

Then, start traversing S, the letter is indexed, directly to the location, then the location value of +1.

After traversing S, this data structure is set up, and, state data structure is also built up , if the same through machine learning, it is already a usable state, such as shown in the screenshot below:
Constructing a data structure

Finally, use this data to build a good structure, traversing the letters J, the number of direct found this letter appears, the problem can be solved.

Here design an array to build a data structure, but this is only an example, just to illustrate "to design a data structure" routine , as to what kind of data structure, is given a choice, like for that matter, We can also design a hash table, represented by the letters S key, and the value is the number of occurrences of the letter, and they can elegantly solve the problem.

Therefore, it is important routines, rather than specific performance unless specific performance has become a key issue.

Above, describes how according to the specific problem, build a proper data structure, the focus is to have data structures to build awareness.

Finally, two small way to achieve given the code and leecode feedback and end of the main content of this article:

// c code
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

int numJewelsInStones(char* J, char* S) {
    int arrlen = 'z'+1;
    char* arr = (char*)malloc(arrlen);
    memset(arr, 0, arrlen);
    for (int i = 0; i < strlen(S); i ++) {
        arr[S[i]] += 1; 
    }
    int cnt = 0;
    for (int j = 0; j < strlen(J); j ++) {
        cnt += arr[J[j]];
    }
    free(arr);
    return cnt;
}

int main(int argc, char *argv[])
{
    char *S = "aAAbbbb", *J = "aA";
    int cnt = numJewelsInStones(J, S);
    printf("cnt=%d\n", cnt);
    return 0;
}

The implementation code submitted to the above leecode, you can see such feedback (fast execution speed, beat 100% c code submitted, the main reason is that with more space):
leecode Feedback 1

// c# code
public int NumJewelsInStones(string J, string S)
{
    int result = 0;

    if (string.IsNullOrEmpty(J) || string.IsNullOrEmpty(S)) return result;

    var kv = new Dictionary<string, int>();
    var sArr = S.ToArray();
    var jArr = J.ToArray();

    //S去重,统计字母出现次数
    int i = 0, v = 1;
    while (i < sArr.Count())
    {
        if (kv.ContainsKey(sArr[i].ToString()))
        {
            kv[sArr[i].ToString()] += v;
            i++;
            continue;
        }

        kv.Add(sArr[i].ToString(), v);
        i++;
    }

    //统计宝石数
    foreach (var kvp in kv)
    {
        if (!J.Contains(kvp.Key)) continue;

        result += kvp.Value;
    }

    return result;
}

Submitted to achieve the above leecode, feedback obtained as follows:
leetcode feedback 2

In summary, this paper describes the design of a regular routine algorithm, that is, to solve problems and to design a data structure. When you encounter a problem, you should give yourself a little time, a certain design, and in the design of algorithms, you should ask yourself: is not the first to design a data structure?


haha

Guess you like

Origin www.cnblogs.com/freeself/p/10945640.html