directory

Problem 1: Integer to Roman numerals

Problem 2: a combination of letters for telephone numbers

Problem 3: all paths to a binary tree

Problem 4: Brick walls

Problem 5: Next permutation

Problem 6: Parenthesis generation

Question 7: Delete and earn points

Problem 8: All permutations

Problem 9: Color classification

Problem 10: grouping of letter heterotopic words


LeetCode brushes the questions regularly, with 10 questions in each period. Comrades with heavy business can look at the ideas I share, which are not the most efficient solutions, but for mutual improvement.

Question 1:Integer to Roman numerals

The requirements are as follows:

Answer:

1. Create two arrays, namely numeric values and Roman character arrays. The Roman number of these two arrays corresponds to the array value.

2, find the corresponding Roman character;

Copy the Roman character into the output string.

Answer (C language) :

#include<string.h>

char * intToRoman(int num){
    //step1: Define an array
    int s[13] = {1000.900.500.400.100.90.50.40.10.9.5.4.1};// Array of values
    char a[13] [3] = {"M"."CM"."D"."CD"."C"."XC"."L"."XL"."X"."IX"."V"."IV"."I"};// Roman character array
    char *res = (char *)calloc(16.sizeof(char));

    int count = 0;// The number of Roman characters copied

    //step2: find the corresponding Roman character
    for(int i = 0; i <13; i++){ count = num / s[i]; num %= s[i];//step3: copy Roman characters
        for(int j = 0; j < count; j++){strcat(res,a[i]);//"strcat": copies the string of a[I] to the end of res}}return res;
}
Copy the code

The operating efficiency is as follows:


Question 2:A combination of letters for a telephone number

The requirements are as follows:

Answer:

Use a Map table to store all possible letters for each number, and then go back and enumerate all the solutions.

Answer (C language) :

/** * Note: The returned array must be malloced, assume caller calls free(). */
char phoneMap[9] [5] = {""."abc"."def"."ghi"."jkl"."mno"."pqrs"."tuv"."wxyz"}; // 1 does not correspond to any letter
/* Note: The returned array must be malloced, assume caller calls free(). */
void backtrack(char* digits, int digits_size, int index, char* item, int item_size, char** ans, int* returnSize) {
    if (index == digits_size) {
        char* tmp = malloc((item_size + 1) * sizeof(char)); // Allocate space for each item
        strcpy(tmp, item); // Copy and save each item
        ans[(*returnSize)++] = tmp;
    } 
    else {
        char* letters = phoneMap[digits[index] - '1'];
        int size = strlen(letters);
        for (int i = 0; i < size; i++) {
            item[item_size++] = letters[i];
            item[item_size] = 0;
            backtrack(digits, digits_size, index + 1, item, item_size, ans, returnSize);
            item[--item_size] = 0; }}}char** letterCombinations(char* digits, int* returnSize) {
    int digits_size = strlen(digits);
    *returnSize = 0;

    if (digits_size == 0) {
        return NULL;
    }

    int num = pow(4, digits_size);
    char** ans = (char* *)malloc(num * sizeof(char*));
    char* item = malloc((digits_size + 1) * sizeof(char));

    backtrack(digits, digits_size, 0, item, 0, ans, returnSize);
    
    return ans;
}
Copy the code

The operating efficiency is as follows:


Question 3:All paths to a binary tree

The requirements are as follows:

Answer:

The most intuitive approach is to use depth-first search. When a depth-first search traverses a binary tree, the current node and its children need to be considered.

  • If the current node is not a leaf node, the node is added at the end of the current path and each child node of the node continues to be recursively traversed.
  • If the current node is a leaf node, add the node at the end of the current path to get a path from the root node to the leaf node. Add the path to the answer.

In this way, when traversing the entire binary tree, we get all the paths from the root node to the leaf node. Of course, depth-first search can also be implemented in a non-recursive way.

Answer (C language) :

/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; *}; * /

/** * Note: The returned array must be malloced, assume caller calls free(). */
void construct_paths(struct TreeNode* root, char** paths, int* returnSize, int* sta, int top) {
    if(root ! =NULL) {
        if (root->left == NULL && root->right == NULL) {  // The current node is a leaf node
            char* tmp = (char*)malloc(1001);
            int len = 0;
            for (int i = 0; i < top; i++) {
                len += sprintf(tmp + len, "%d->", sta[i]);
            }
            sprintf(tmp + len, "%d", root->val);
            paths[(*returnSize)++] = tmp;  // Add the path to the answer
        } else {
            sta[top++] = root->val;  // The current node is not a leaf node, continue recursive traversal
            construct_paths(root->left, paths, returnSize, sta, top);
            construct_paths(root->right, paths, returnSize, sta, top); }}}char** binaryTreePaths(struct TreeNode* root, int* returnSize) {
    char** paths = (char* *)malloc(sizeof(char*) * 1001);
    *returnSize = 0;
    int sta[1001];

    construct_paths(root, paths, returnSize, sta, 0);
    
    return paths;
}
Copy the code

The operating efficiency is as follows:


Question 4:Brick wall

The requirements are as follows:

Answer:

For the current row, we scan each brick from left to right, use an accumulator to record the distance from the right edge of the current brick to the left edge of the brick, and add the distance from the right edge to the left edge of the brick except the right-most brick to the hash table. Finally, we iterate through the table to find the most common brick edge, which is the brick edge that the vertical line passes through, and the number of bricks that the vertical line passes through is the height of the brick wall minus the number of brick edges that the vertical line passes through.

Answer (C language) :

struct HashTable {
    int key, val;
    UT_hash_handle hh;
};

int leastBricks(int** wall, int wallSize, int* wallColSize) {
    struct HashTable* cnt = NULL;
    for (int i = 0; i < wallSize; i++) {
        int n = wallColSize[i];
        int sum = 0;
        for (int j = 0; j < n - 1; j++) {
            sum += wall[i][j];
            struct HashTable* tmp;
            HASH_FIND_INT(cnt, &sum, tmp);
            if (tmp == NULL) {
                tmp = malloc(sizeof(struct HashTable));
                tmp->key = sum, tmp->val = 1;
                HASH_ADD_INT(cnt, key, tmp);
            } else{ tmp->val++; }}}int maxCnt = 0;
    struct HashTable *iter, *tmp;
    HASH_ITER(hh, cnt, iter, tmp) {
        maxCnt = fmax(maxCnt, iter->val);
    }
    return wallSize - maxCnt;
}
Copy the code

The operating efficiency is as follows:


Question 5:Next permutation

The requirements are as follows:

Answer (C language) :

void swap(int *a, int *b) {
    int t = *a;
    *a = *b, *b = t;
}

void reverse(int *nums, int left, int right) {
    while (left < right) {
        swap(nums + left, nums + right); left++, right--; }}void nextPermutation(int *nums, int numsSize) {
    int i = numsSize - 2;

    while (i >= 0 && nums[i] >= nums[i + 1]) {
        i--;
    }
    if (i >= 0) {
        int j = numsSize - 1;
        while (j >= 0 && nums[i] >= nums[j]) {
            j--;
        }
        swap(nums + i, nums + j);
    }
    
    reverse(nums, i + 1, numsSize - 1);
}
Copy the code

The operating efficiency is as follows:


Question 6:Parentheses generates

The requirements are as follows:

Answer:

Backtracking algorithm recursive solution: if the number of open parentheses is not greater than n, we can put an open parenthesis. If the number of close parentheses is less than the number of open parentheses, we can put a close parentheses.

Answer (C language) :

// backtracking
#define MAX_SIZE 1430  // Catalan number: 1, 1, 2, 5, 14, 42, 132, 429, 1430

void generate(int left, int right, int n, char *str, int index, char **result, int *returnSize) {
    if (index == 2 * n) { // The current length is 2N
        result[(*returnSize)] =  (char*)calloc((2 * n + 1), sizeof(char));
        strcpy(result[(*returnSize)++], str);
        return;
    }
    // If the number of open parentheses is not greater than n, an open parenthesis can be placed
    if (left < n) {
        str[index] = '(';
        generate(left + 1, right, n, str, index + 1, result, returnSize);
    }
    // If the number of close parentheses is less than the number of open parentheses, you can put a close parentheses
    if (right < left) {
        str[index] = ') ';
        generate(left, right + 1, n, str, index + 1, result, returnSize); }}/** * Note: The returned array must be malloced, assume caller calls free(). */
char** generateParenthesis(int n, int *returnSize) {
    char *str = (char*)calloc((2 * n + 1), sizeof(char));
    char **result = (char* *)malloc(sizeof(char *) * MAX_SIZE);
    *returnSize = 0;
    generate(0.0, n, str, 0, result, returnSize);
    return result;
}
Copy the code

The operating efficiency is as follows:


Question 7:Delete and earn points

The requirements are as follows:

Answer (C language) :

int rob(int *nums, int numsSize) {
    int first = nums[0], second = fmax(nums[0], nums[1]);
    
    for (int i = 2; i < numsSize; i++) {
        int temp = second;
        second = fmax(first + nums[i], second);
        first = temp;
    }

    return second;
}

int deleteAndEarn(int *nums, int numsSize) {
    int maxVal = 0;

    for (int i = 0; i < numsSize; i++) {
        maxVal = fmax(maxVal, nums[i]);
    }

    int sum[maxVal + 1];
    memset(sum, 0.sizeof(sum));

    for (int i = 0; i < numsSize; i++) {
        sum[nums[i]] += nums[i];
    }

    return rob(sum, maxVal + 1);
}
Copy the code

The operating efficiency is as follows:


Question 8:The whole arrangement

The requirements are as follows:

Answer (C language) :

/** * Return an array of arrays of size *returnSize. * The sizes of the arrays are returned as *returnColumnSizes array.  * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free(). */
 
int count;

void dfs(int* nums,int numsSize,int depth,int* cur,bool* used,int** res){
    if(depth==numsSize){
        res[count]=(int*)malloc(numsSize*sizeof(int));
        memcpy(res[count++],cur,numsSize*sizeof(int));
        return;
    }

    for(int i=0; i<numsSize; ++i){if(used[i]==true) continue;
        cur[depth]=nums[i];
        used[i]=true;
        //++depth;

        dfs(nums,numsSize,depth+1,cur,used,res);
        
        //--depth;
        used[i]=false; }}int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
    int s=1;
    for(int i=1; i<=numsSize; ++i) s*=i;int** res=(int* *)malloc(s*sizeof(int*));

    bool* used=(bool*)malloc(numsSize*sizeof(bool));
    memset(used,0,numsSize*sizeof(bool));

    int* cur=(int*)malloc(numsSize*sizeof(int));

    count=0;
    dfs(nums,numsSize,0,cur,used,res);
    
    *returnSize=s;
    *returnColumnSizes=(int*)malloc(s*sizeof(int));
    for(int i=0; i<s; ++i) (*returnColumnSizes)[i]=numsSize;return res;
}
Copy the code

The operating efficiency is as follows:


Question 9:Color classification

The requirements are as follows:

Answer (C language) :

void swap(int *a, int *b) {
    int t = *a;
    *a = *b, *b = t;
}

void sortColors(int *nums, int numsSize) {
    int ptr = 0;
    
    for (int i = 0; i < numsSize; ++i) {
        if (nums[i] == 0) {
            swap(&nums[i], &nums[ptr]); ++ptr; }}for (int i = ptr; i < numsSize; ++i) {
        if (nums[i] == 1) {
            swap(&nums[i], &nums[ptr]); ++ptr; }}}Copy the code

The operating efficiency is as follows:


Question 10:Grouping of letter ectopic words

The requirements are as follows:

Answer:

1. Sort the string first to see if it is an allotopic word.

2. Store a hashtable containing a string of heterotopic words from small to large;

3. Check ht to determine whether a new line of result needs to be created.

4. Insert string in ht by Str->id.

5. If there is no HT, create a new line in result.

Answer (C language) :

#define STR_MAX_LEN 10000

static int compare(const void* x, const void* y)
{
    return* (char*)x - *(char*)y;
}

struct Str {
    char key_str[STR_MAX_LEN];
    int id;
    UT_hash_handle hh;
};

char* * *groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes)
{
    if (strs == NULL || strsSize < 0) {
        return NULL;
    }
    struct Str *keyStrsHash = NULL, *str = NULL;
    char ***result = (char* * *)malloc(sizeof(char **) * strsSize);
    char **sortedStrs = (char* *)malloc(sizeof(char *) * strsSize);
    *returnSize = 0;
    *returnColumnSizes = (int *)malloc(sizeof(int) * strsSize);

    for (int i = 0; i < strsSize; i++) {
        int len = strlen(strs[i]);
        sortedStrs[i] = (char*)malloc(len + 1);
        (void)strcpy(sortedStrs[i], strs[i]);
        qsort(sortedStrs[i], len, sizeof(char), compare);
        
        HASH_FIND_STR(keyStrsHash, sortedStrs[i], str);
        if(! str) { str = (struct Str*)malloc(sizeof(struct Str));
            strcpy(str->key_str, sortedStrs[i]);
            str->id = *returnSize;
            HASH_ADD_STR(keyStrsHash, key_str, str);

            result[*returnSize] = (char* *)malloc(sizeof(char*) * strsSize);
            result[*returnSize][0] = (char*)malloc(len + 1);
            strcpy(result[*returnSize][0], strs[i]);

            (*returnColumnSizes)[*returnSize] = 1;
            (*returnSize)++;
        } else {
            int row = str->id;
            int col = (*returnColumnSizes)[row];
            result[row][col] = (char*)malloc(len + 1);
            strcpy(result[row][col], strs[i]); ((*returnColumnSizes)[row])++; }}HASH_CLEAR(hh, keyStrsHash);
    for (int i = 0; i < strsSize; i++) {
            free(sortedStrs[i]);
    }
    return result;
}
Copy the code

The operating efficiency is as follows: