LeetCode notes (C language version, September)

Keywords: Algorithm data structure leetcode





Day Practise - 3 problems one day

2021.9.16 1 - 3

2021.9.17 4 - 6

2021.9.18 7 - 9

2021.9.19 10 - 12

2021.9.20 13 - 15

2021.9.21 16 - 18

2021.9.22 19 - 21 3h

2021.9.23 22 - 24 2h

2021.9.24 25 - 27 1h40m

2021.9.25 28 - 30 1h8m

2021.9.26 31 - 33 1h28m

2021.9.27 34 - 36 34m

2021.9.28 37 - 39 2h10m 40 - 1h40m

2021.9.29 40 - 42 2h 42 - 45(SQL)

2021.9.30 43 - 45

1. Binary search

Find the subscript of the element in the array

int search(int* nums, int numsSize, int target){
    int low = 0;
    int high = numsSize - 1;
    int mid = 0;
    while(low <= high){
        mid = (low + high) / 2;
        if(nums[mid] < target){
            low = mid + 1;
        } else if(nums[mid] > target){
            high = mid - 1;
        } else if(nums[mid] == target){
            return mid;
        }
    }
    return -1;          //No relevant information was found
}

2. Search insertion location

Given a sort array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, returns the position where it will be inserted in order.

Example

input 
	nums = [1,3,5,6], target = 5
 output 
	2

code

int searchInsert(int* nums, int numsSize, int target){
    int left = 0;
    int right = numsSize - 1;
    int mid;
    //Binary search
    while (left <= right)
    {
        mid = (left + right) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        }
        else if (nums[mid] > target) {
            right = mid - 1;
        }
        else {
            return mid;
        }
    }
    //If not found, returns the position where it will be inserted in order.
    return (nums[mid] > target) ? mid : mid + 1;
}

3. Flip shaping number

Give you a 32-bit signed integer x and return the result after reversing the number part in X. If the inverted integer exceeds the range of 32-bit signed integers [− 231, 231 − 1], 0 is returned.

Example

Example 1:
	Input: x = 123 
	Output: 321
 Example 2:
	Input: x = -123 
	Output:-321

code

int reverse(int x){
  int rev = 0;
    while (x != 0) {
        if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {
            return 0;
        }
        int digit = x % 10;
        x /= 10;
        rev = rev * 10 + digit;
    }
    return rev;
}

Write it yourself - no error in code::blocks

int reverse(int x){
    int t = x,i;
    int length = 0;

    while(t){
        length+=1;
        t /= 10;
    }

    //Define array
    int * nums;
    nums = (int *)malloc(sizeof(int) * length);

    for(i = 0;i < length;i++){
        nums[i] = x % 10;
        x /= 10;
    }

    int result = 0;
    for(i = length;i > 0;i--){
        result += nums[length-i]  * pow(10,i-1);
    }

    //Verify boundary conditions
    if (result < INT_MIN / 10  || result > INT_MAX / 10) {
        return 0;
    }
    return result;
}

4. Determine whether it is a palindrome integer

Give you an integer X. if x is a palindrome integer, return true; Otherwise, false is returned.

Palindromes are integers that are read in the same positive order (from left to right) and reverse order (from right to left). For example, 121 is palindrome and 123 is palindrome

no

 bool isPalindrome(int x) {
        int rev = 0;
        int input = x;
        while (x != 0) {
            if (rev < INT_MIN / 10 || rev > INT_MAX / 10) {
                return 0;
            }
            int digit = x % 10;
            x /= 10;
            rev = rev * 10 + digit;
        }
        
        if(rev == input && input >= 0)
            return true;
        else{
            return false;
        }
}

5. Gray histogram (CCF 2021-04-1)

Example

sample input 
	4 4 16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
 sample output 
	1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 analysis
	Given matrix size  n × m  Maximum value of matrix element ≤ L
	input n m L Three values determine the gray histogram array of the image,That is, array position 0 - L Corresponds to the number of occurrences of elements in the matrix.

answer

The violence method is directly used here. Three-layer traversal is used for statistics, and the array size is limited to 500 × 500 and dynamically allocate array space

code

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>


int main()
{
    int n,m,L;
    int * nums;
    int i,j,k;
    scanf("%d%d%d",&n,&m,&L);
    nums = (int *)malloc(sizeof(int) * L);
    for(i = 0;i < L;i++)
        nums[i] = 0;

    int array[500][500];
    for(i = 0;i < n;i++){
        for(j = 0;j < m;j++){
            scanf("%d",&array[i][j]);
        }
    }

    for(i = 0;i < n;i++){
        for(j = 0;j < m;j++){
            for(k = 0;k < L;k++)
                if(array[i][j] == k)
                    nums[k]++;
        }
    }

    for(i = 0;i < L;i++)
        printf("%d ",nums[i]);

    return 0;
}

6. Roman numeral to integer

Roman numerals contain the following seven characters: I, V, X, L, C, D and M.

character          numerical value
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

For example, the Roman numeral 2 is written as II, which is two parallel ones. 12 is written as XII, which is X + II. 27 is written as XXVII, which is XX + V + II.

Usually, the small Roman numerals are to the right of the large ones. But there are also special cases. For example, 4 is not written as IIII, but IV. The number 1 is on the left of the number 5, and the number represented is equal to the value 4 obtained by subtracting the decimal 1 from the large number 5. Similarly, the number 9 is represented as IX. This special rule applies only to the following six cases:

I can be placed to the left of V (5) and X (10) to represent 4 and 9.
X can be placed to the left of L (50) and C (100) to represent 40 and 90.
C can be placed to the left of D (500) and M (1000) to represent 400 and 900.
Given a Roman numeral, convert it to an integer.

Example

Example 1:
	input: "III"
	output: 3
 Example 2:
    input: s = "IV"
    output: 4
 Example 3:
    input: s = "IX"
    output: 9
 Example 4:
    input: s = "LVIII"
    output: 58
    explain: L = 50, V= 5, III = 3.
Example 5:
    input: s = "MCMXCIV"
    output: 1994
    explain: M = 1000, CM = 900, XC = 90, IV = 4.

code

Violence method, that is, solve most problems first, and then deal with the boundary to make it conform to the rules as much as possible (here you can use an array to simplify the code, and then modify it later when you have a chance).

int romanToInt(char * s){
    int result = 0;
    while(*s){
        //The following IF is used for boundary treatment
        if(*s == 'I' && *(s+1) == 'V')
        {
            result += 4;
            s+=2;
            continue;
        }
        else if(*s == 'I' && *(s+1) == 'X')
        {
            result += 9;
            s+=2;
            continue;
        }
        else if(*s == 'X' && *(s+1) == 'L')
        {
            result += 40;
            s+=2;
            continue;
        }
        else if(*s == 'X' && *(s+1) == 'C')
        {
            result += 90;
            s+=2;
            continue;
        }
        else if(*s == 'C' && *(s+1) == 'D')
        {
            result += 400;
            s+=2;
            continue;
        }
        else if(*s == 'C' && *(s+1) == 'M')
        {
            result += 900;
            s+=2;
            continue;
        }

        //Do the following general operations
        if(*s == 'I')
            result += 1;
        else if(*s == 'V')
            result += 5;
        else if(*s == 'X')
            result += 10;
        else if(*s == 'L')
            result += 50;
        else if(*s == 'C')
            result += 100;
        else if(*s == 'D')
            result += 500;
        else if(*s == 'M')
            result += 1000;
        s++;
    }
    return result;
}

Official solution

int romanToInt(char* s) {
    int symbolValues[26];
    symbolValues['I' - 'A'] = 1;
    symbolValues['V' - 'A'] = 5;
    symbolValues['X' - 'A'] = 10;
    symbolValues['L' - 'A'] = 50;
    symbolValues['C' - 'A'] = 100;
    symbolValues['D' - 'A'] = 500;
    symbolValues['M' - 'A'] = 1000;
    int ans = 0;
    int n = strlen(s);
    for (int i = 0; i < n; ++i) {
        int value = symbolValues[s[i] - 'A'];
        if (i < n - 1 && value < symbolValues[s[i + 1] - 'A']) {
            ans -= value;
        } else {
            ans += value;
        }
    }
    return ans;
}

7. Square of ordered array

Give you an integer array nums sorted in non decreasing order, and return a new array composed of the square of each number. It is also required to sort in non decreasing order.

Example

Example 1:
    Input: nums = [-4,-1,0,3,10]
    Output:[0,1,9,16,100]
Example 2:
    Input: nums = [-7,-3,2,3,11] 
    Output:[4,9,9,49,121]

code

Dynamic allocation of groups and bubble sorting of the results obtained by pow function with square complexity O(n ²)

int * sortedSquares(int* nums, int numsSize, int* returnSize){
    int i,j;
    int * array = (int *)malloc(sizeof(int)*numsSize);
    for(i = 0;i < numsSize;i++){
        array[i] = pow(nums[i],2);
    }

    for(i = 0;i < numsSize - 1;i++){
        for(j = 0;j < numsSize - i -1;j++){
            if(array[j] > array[j+1]){
                int temp = array[j];
                array[j] = array[j+1];
                array[j+1] = temp;
            }
        }
    }

    * returnSize = numsSize;
    return array;
}

8. Rotate array

Given an array, move the elements in the array K positions to the right, where k is a non negative number.

Example

Example 1:
	input: nums = [1,2,3,4,5,6,7], k = 3
	output: [5,6,7,1,2,3,4]
explain:
	Rotate 1 step to the right: [7,1,2,3,4,5,6]
	Rotate 2 steps to the right: [6,7,1,2,3,4,5]
	Rotate 3 steps to the right: [5,6,7,1,2,3,4]

code

The algorithm uses the violent solution, that is, it operates directly on the array to simulate the rotation, that is, it moves the array elements right once, so the complexity is high.

void rotate(int* nums, int numsSize, int k){
    int i,temp,j;
    for(i = 0;i < k;i++){
        temp = nums[numsSize-1];    //Get the last element
        //Backward overlay
        for(j = numsSize - 1;j > 0;j--)
            nums[j] = nums[j-1];        //cover
        //Restore team head element
        nums[0] = temp;
    }
}

The algorithm borrows the auxiliary space, directly calculates the rotated result, and then assigns it back to the result array. The difficulty lies in the determination and logical extraction of the position of the array subscript after rotation.

void rotate(int* nums, int numsSize, int k){
    int i,temp,j;
    int * array = (int *)malloc(sizeof(int)*numsSize);
    for(i = 0;i < numsSize;i++){
        array[(i+ k) % numsSize] = nums[i];
    }
    for(i = 0;i < numsSize;i++){
        nums[i] = array[i];
    }
}

9. Move zero element

Given an array num, write a function to move all zeros to the end of the array while maintaining the relative order of non-zero elements.

Example

Example:
	input: [0,1,0,3,12]
	output: [1,3,12,0,0]
explain
	You must operate on the original array and cannot copy additional arrays.
	Minimize the number of operations.

code

The algorithm uses the idea of insertion sorting, first counts the number of 0 for subsequent coverage, then inserts each element into the final position (i.e. the final position) in order, and finally restores the zero element.

void moveZeroes(int* nums, int numsSize){
    int i;
    int count = 0;
    //Count the number of 0
    for(i = 0;i < numsSize;i++)
        if(nums[i] == 0)
            count++;
    
    //Move element
    int final = 0;      //Records the number of elements that have been moved to the specified location
    for(i = 0;i < numsSize;i++){
        if(nums[i]){
            nums[final] = nums[i];
            final++;
        } 
    }

    //Restore 0 to end
    for(i = 0;i < count;i++){
        nums[final+i] = 0;
    }
}

10. Sum of two numbers

Given an integer array nums and an integer target value target, please find the two integers with and as the target value target in the array and return their array subscripts.

You can assume that each input will correspond to only one answer. However, the same element in the array cannot appear repeatedly in the answer.

Example

Example 1:
	Input: nums = [2,7,11,15], target = 9
	Output:[0,1]
	Explanation: because nums[0] + nums[1] == 9 ,return [0, 1] . 

code

The algorithm completes the calculation by means of violent iteration

int* twoSum(int* nums, int numsSize, int target, int* returnSize){
    int i,j;
    //Violent iteration complete lookup
    for(i = 0;i < numsSize;i++){
        for(j = i+1;j < numsSize;j++){
            if(nums[i] + nums[j] == target){
                int * result = (int *)malloc(sizeof(int)*2);
                result[0] = i;
                result[1] = j;
                *returnSize = 2;
                return result;
            }
        }
    }
    *returnSize = 0;
    return NULL;
}

11. Safety index predicted at the end of the period (CCF 202012-1)

Example

Example 1
	input	6 2 60 10 100 0 70 0 0 -10 50 10 60
	output	1220

code

The problem is relatively simple. You can do it after reading the meaning. In essence, it is to do a max(0,x) operation and sum.

#include <stdio.h>
#include <stdlib.h>

int ReLU(int nums[100000][2],int n){
    int i,j;
    int result = 0;
    for(i = 0;i < n;i++){
        result += nums[i][0] * nums[i][1];
    }
    return result > 0 ? result : 0;
}

int main()
{
    int nums[100000][2];        //data
    int n,i,j;
    scanf("%d",&n);
    for(i = 0;i < n;i++){
        for(j = 0;j < 2;j++){
            scanf("%d",&nums[i][j]);
        }
    }
    printf("%d",ReLU(nums,n));
    return 0;
}

12. Flip string

Write a function to reverse the input string. The input string is given in the form of character array char []. Do not allocate additional space to another array. You must modify the input array in place and use the additional space of O(1) to solve this problem.

You can assume that all characters in the array are printable characters in the ASCII code table.

Example

Example 1:
	Input:["h","e","l","l","o"] 
	Output:["o","l","l","e","h"]

code

The algorithm exchanges the characters at the corresponding position, and the number of execution is length / 2

void reverseString(char* s, int sSize){
    int i;
    for(i = 0;i < sSize/2;i++){
        char temp;
        temp = s[i];
        s[i] = s[sSize-i-1];
        s[sSize-i-1] = temp;
    }
}

13. Flip words in string

Given a string, you need to reverse the character order of each word in the string while still retaining the initial order of spaces and words.

Example

Input:"Let's take LeetCode contest"
Output:"s'teL ekat edoCteeL tsetnoc"

code

The algorithm is based on the official solution, and the basic ideas are consistent with it.

Open up a new string. Then traverse the original string from beginning to end until a space is found. At this time, a word is found and the start and end position of the word can be obtained. Then, according to the start and end position of the word, the word can be placed in the new string in reverse order. Repeat this cycle many times until the original string is traversed, and the flipped result can be obtained.

char * reverseWords(char * s) {
    int length = strlen(s);
    char * result = (char*)malloc(sizeof(char) * (length + 1));
    result[length] = 0;
    int i = 0,j;
    int start;
    while(1){
        start = i;      //The position where the assignment starts
        while(s[i] != ' ' && i < length)
            i++;

        for(j = start;j < i;j++){
            result[j] = s[start + i - 1 - j];     //Because i-1 is constant, you need to add another argument
        }

        while(s[i] == ' ' && i < length){
            result[i] = ' ';
            i++;
        }

        if(i >= length){
            break;
        }
    }

    return result;
}

14. Intermediate node of linked list

Given a non empty single linked list with head node, return the intermediate node of the linked list. If there are two intermediate nodes, the second intermediate node is returned.

Example

Example 1
	Input:[1,2,3,4,5]
	Output: node 3 in this list (Serialization form:[3,4,5])
	The returned node value is 3. (The serialization expression of this node in the evaluation system is [3,4,5]). 
	Notice that we returned a ListNode Object of type ans,So:
	ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, as well as 	
	ans.next.next.next = NULL.

Example 2
	Input:[1,2,3,4,5,6]
	Output: node 4 in this list (Serialization form:[4,5,6])
	Since the list has two intermediate nodes with values of 3 and 4, we return the second node.

answer

The algorithm determines the position of the median by the length of the linked list, and then obtains the corresponding results.

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode * p,*q,*result;
    //result = (ListNode *)malloc(sizeof(ListNode));
    p = head;
    q = head;

    int length = 0;     //Get the length of the linked list

    while(p){
        length++;
        p = p->next;
    }

    int tag = 0;
    if(length % 2 != 0){
        tag = length / 2;
        while(tag--){
            q = q->next;
        }
        result = q;
    } else if(length % 2 == 0){
        tag = length / 2;
        while(tag--)
            q = q->next;
        result = q;
    }
    return result;
}

15. Flip string

Give you a linked list, delete the penultimate node of the linked list, and return the head node of the linked list.

Example

Example 1:
	Input: head = [1,2,3,4,5], n = 2 
	Output:[1,2,3,5]
Example 2:
	Input: head = [1], n = 1 
	Output:[]

code

The algorithm uses a large number of intermediate variables. Firstly, the non leading node is transformed into the leading node to simplify the operation, and then the head part of the leading node is processed.

struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
    //Non leading node structure
    struct ListNode * p,* q,*result;
    p = (struct ListNode *)malloc(sizeof(struct ListNode));
    q = (struct ListNode *)malloc(sizeof(struct ListNode));
    //Construction head node
    p->next = head;
    q->next = head;
    result = q;
    int length = 0;
    //Get linked list length
    while(p->next){
        length++;
        p = p->next;
    }

    //Move the node to the header node where you want to remove it
    int i;
    for(i = 0;i < length - n;i++){
        q = q->next;
    }

    //Handle header nodes
    if(length > 0)
        q->next = q->next->next;        //Remove node
    else if(length == 1)
        q->next = NULL;
    return result->next;
}

16. Longest substring without duplicate characters

Given a string s, please find the length of the longest substring that does not contain duplicate characters.

Example

Example 1:
	input: s = "abcabcbb"
	output: 3 
	explain: Because the longest substring without duplicate characters is "abc",So its length is 3.
Example 2:
	input: s = "bbbbb"
	output: 1
	explain: Because the longest substring without duplicate characters is "b",So its length is 1.

code

It took 2 hours to write the algorithm. Basically, BF, that is, sliding, is used to repeatedly compare whether the comparison position of the matching string is repeated compared with the previous one, and the corresponding results are obtained.

//String matching
int lengthOfLongestSubstring(char * s){
    //Records all characters that appear in the string
    char * str;
    str = (char *)malloc(sizeof(char) * strlen(s) + 1);
    int i,j,k;
    int length = 0;
    int max = 0,result = 0;
    int flag = 0;       //Match location
    for(i = 0;i < strlen(s);i++){

        //Determine whether the matching string is repeated
        for(j = 0;j < length;j++){
            //Duplicate with previous match
            if(s[i] == str[j]){
                break;
            }
        }

        //If not repeated
        if(j == length){
            str[length++] = s[i];       //Assign value to matching string
            max++;
        }
        //If repeated
        else if(j != length){
            if(result < max)
                result = max;
            max = 0;  //Max reset
            length = 0;  //Match string length reset
            strcpy(str,"");   //Clear str array
            flag++;   //Slide position forward
            i = flag-1;       //The purpose of sliding here - 1 is to erase the function of for loop i + +
        }
    }
    //When max is obtained from the tail, there may be no repetition, that is, the result will not be assigned, so it needs to be judged again
    if(result < max)
        result = max;
    return result;
}

17. Arrangement of strings (the concept of arrangement is not understood)

Give you two strings s1 and s2 and write a function to determine whether s2 contains the arrangement of s1.

In other words, one of the permutations of s1 is a substring of s2.

Example

Example 1:
	Input: s1 = "ab" s2 = "eidbaooo"
	Output: true
	Explanation: s2 contain s1 One of the permutations of ("ba").

code

Official answer

bool checkInclusion(char* s1, char* s2) {
    int n = strlen(s1), m = strlen(s2);
    if (n > m) {
        return false;
    }
    int cnt[26];
    memset(cnt, 0, sizeof(cnt));
    for (int i = 0; i < n; ++i) {
        --cnt[s1[i] - 'a'];
    }
    int left = 0;
    for (int right = 0; right < m; ++right) {
        int x = s2[right] - 'a';
        ++cnt[x];
        while (cnt[x] > 0) {
            --cnt[s2[left] - 'a'];
            ++left;
        }
        if (right - left + 1 == n) {
            return true;
        }
    }
    return false;
}

18. Longest common prefix

Write a function to find the longest common prefix in a string array.

Returns the empty string '' if there is no public prefix.

Example

Example 1:
	Input: strs = ["flower","flow","flight"] 
	Output:"fl"

code

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) {
            return "";
        }
        int length = strs[0].length();
        int count = strs.length;
        for (int i = 0; i < length; i++) {
            char c = strs[0].charAt(i);
            for (int j = 1; j < count; j++) {
                if (i == strs[j].length() || strs[j].charAt(i) != c) {
                    return strs[0].substring(0, i);
                }
            }
        }
        return strs[0];
    }
}

19. Merge two ordered linked lists

Merge the two ascending linked lists into a new ascending linked list and return. The new linked list is composed of all nodes of a given two linked lists.

Example

Example 1:
	Input: l1 = [1,2,4], l2 = [1,3,4] 
	Output:[1,1,2,3,4,4]
Example 2:
	Input: l1 = [], l2 = [] 
	Output:[]

code

The test environment given by the topic does not have a lead node, so it is necessary to construct a head node for it. The main idea is to first merge the two linked lists, bubble the values of the linked list after merging, and finally assign values back to the linked list (here you can directly use the linked list for bubble sorting).

struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
    struct ListNode * head1 = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode * head2 = (struct ListNode*)malloc(sizeof(struct ListNode));
    head1->next = l1;
    head2->next = l2;
    struct ListNode *p,*q,*k;
    int i,j;
    p = head1;
    q = head2;
    k = head1;
    while(p->next){
        p = p->next;
    }
    p->next = q->next;        //Link two linked lists

    //Calculation length
    int length = 0;
    while(k->next){
        k = k->next;
        length++;
    }

    int * nums = (int *)malloc(sizeof(int) * length);
    //assignment
    k = head1->next;
    i = 0;
    while(k){
        nums[i++] = k->val;
        k = k->next;
    }

    for(i = 0;i < length - 1;i++){
        for(j = 0;j < length - i - 1;j++){
            if(nums[j] > nums[j+1]){
                int temp = nums[j];
                nums[j] = nums[j+1];
                nums[j+1] = temp;
            }
        }
    }

    p = head1->next;
    i = 0;
    while(p){
        p->val = nums[i++];
        p = p->next;
    }

    return head1->next;
}

20. Remove duplicates from an ordered array

Give you an ordered array nums, please delete the repeated elements in place, make each element appear only once, and return the new length of the deleted array.

Do not use additional array space. You must modify the input array in place and complete it with O(1) additional space.

Example

Example 1:
	Input: nums = [1,1,2]
	Output: 2, nums = [1,2]
	Explanation: the function should return a new length of 2 and the original array nums The first two elements of are modified to 1, 2 . Arrays do not need to be considered
	The element after the new length is exceeded in.

code

The algorithm uses the idea of insertion sorting, inserts each element with different values of the ordered array into the tag position of the array in order, and updates the tag in time. At the same time, in order to reduce the complexity, we compare the repeated elements and update the sequential variable i to skip the cycle of calling the repeated variables, so as to reduce the time complexity.

int removeDuplicates(int* nums, int numsSize){
    int tag = 0;
    int i,j;
    for(i = 0;i < numsSize;i++){
        int temp = nums[i];
        for(j = i;j < numsSize-1 && temp == nums[j+1];j++){
            i++;        //Back jump
        }
        nums[tag++] = temp;
    }
    return tag;
}

21. Remove elements

Give you an array num and a value val. you need to remove all elements with a value equal to Val in place and return the new length of the removed array.

Instead of using extra array space, you must use only O(1) extra space and modify the input array in place.

The order of elements can be changed. You don't need to consider the elements in the array beyond the new length.

Example

Example 1:
	Input: nums = [3,2,2,3], val = 3
	Output: 2, nums = [2,2]
Explanation: the function should return a new length of 2, also nums The first two elements in the array are both 2. You don't need to consider the elements in the array that exceed the new length. For example, the new length returned by the function is 2, and nums = [2,2,3,3] or nums = [2,2,0,0],It will also be regarded as the correct answer.

code

The algorithm modifies the loop condition on the basis of 20, and performs the insertion operation when the array value is not equal to the element to be deleted, and performs the back jump when the array value is equal to the element value to be deleted, that is, ignores the assignment.

int removeElement(int* nums, int numsSize, int val){
    int tag = 0;
    int i,j;
    for(i = 0;i < numsSize;i++){
        for(j = i;j < numsSize-1 && val == nums[j];j++){
            i++;        //Back jump
        }
        //Boundary condition - last element value judgment
        if(i == numsSize-1 && val == nums[i])
            break;
        nums[tag++] = nums[i];
    }
    return tag;
}

22. Implement str ()

Implement the strStr() function.

Here are two strings, haystack and need. Please find the first position where the need string appears in the haystack string (the subscript starts from 0). If it does not exist, it returns - 1.

Example

When needle What value should we return when it is an empty string? This is a good question in the interview.
For this question, when needle We should return 0 when it is an empty string. This is the same as C Linguistic strstr() as well as Java of indexOf() The definition does not match.
Example 1:
	Input: haystack = "hello", needle = "ll"    
	Output: 2

code

Official solution

int strStr(char* haystack, char* needle) {
    int n = strlen(haystack), m = strlen(needle);
    for (int i = 0; i + m <= n; i++) {
        bool flag = true;
        for (int j = 0; j < m; j++) {
            if (haystack[i + j] != needle[j]) {
                flag = false;
                break;
            }
        }
        if (flag) {
            return i;
        }
    }
    return -1;
}

Self solution

The main body of the algorithm is the optimized BF algorithm, which can pass the execution, but there is no reason to report running errors and timeout errors, so the efficiency of the algorithm may not be high. The KMP algorithm should be optimal, but I don't want to copy jobs here, so the optimized BF algorithm is realized, focusing on the main string movement after mismatch.

int strStr(char * haystack, char * needle){
    int i;
    int tag = 0;
    int hayLength = strlen(haystack);
    int temp = hayLength;
    //Empty string
    if(strlen(needle) == 0)
        return 0;
    if(strlen(needle) > strlen(haystack))
        return -1;

    //BF solution
    while(*haystack){
        //string matching 
        for(i = 0;i < strlen(needle);i++){
            //Matching failed
            if(*(haystack+i) != *(needle+i))
                break;
        }
        //Match successful
        if(i == strlen(needle))
            break;
        if(temp + i <=  hayLength)
            haystack += i;      //KMP Backjump - Optimization

        tag++;
        haystack++;
        temp--;     //Record remaining length
    }

    //Not found
    if(tag == hayLength)
        return -1;

    return tag;
}

23. Maximum subsequence sum (dynamic programming)

Given an integer array nums, find a continuous sub array with the largest sum (the sub array contains at least one element) and return its maximum sum.

Example

Example 1:
	Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
	Output: 6
	Explanation: continuous subarray [4,-1,2,1] The sum of is 6.

code

Official algorithm dynamic programming solution (minus redundant tree nodes)

Take the current point as the end point and store the optimal result of the previous operation.

For this question, such as sequence: - 1 - 1 3

Corresponding to f(1), f(2), f(3) and f(4), the calculation starting from 0 subscript stores the optimal result of each subscript as the end point.

That is, f (1) = 1, f (2) = 1, f (3) = 1, f (4) = 3, so the final result is 3.

int maxSubArray(int* nums, int numsSize) {
    int pre = 0, maxAns = nums[0];
    for (int i = 0; i < numsSize; i++) {
        pre = fmax(pre + nums[i], nums[i]);
        maxAns = fmax(maxAns, pre);
    }
    return maxAns;
}

Algorithm:

The following algorithm uses the violence method, that is, the sliding window method (the interval is I (1 - numsize)) to continuously slide the comparison, circularly obtain the sum of all constructable continuous subsequences, and compare the results one by one. However, according to the loop structure, its complexity is relatively high, and the three-tier for is close O ( n 3 ) . O(n^3). O(n3).

int maxSubArray(int* nums, int numsSize){
    int tag = 0;        //Controls the number of items added each time
    int i,j,k;
    int max = nums[0];
    int temp = 0;
    for(i = 0;i < numsSize;i++){
        tag = i+1;          //Control the number of additions each time 1 2 3 4 5

        //numsSize - i + 1      1 9 - 2 8 - 3 7 - 4 6
        for(j = 0;j < numsSize - i;j++){
            for(k = 0;k < tag;k++){
                //Prevent subscript out of bounds
                if(k+j >= numsSize)
                    break;

                temp += nums[k+j];
            }
            if(max < temp)
                max = temp;
            temp = 0;       //Reset to 0 for next addition
        }
    }
    return max;
}

24. Length of the last word

Give you a string s, which consists of several words, separated by some space characters. Returns the length of the last word in a string.

A word is the largest substring that consists of only letters and does not contain any space characters.

Example

Example 1:
	Input: s = "Hello World"
	Output: 5

code

The algorithm uses the idea of double pointer, that is, pre and cur are used to save the record of word length. Pre is updated when the current character is not empty, and cur is set to 0 when the character is null for recalculation. This keeps sliding and returns the result when s terminates.

int lengthOfLastWord(char * s){
    int i;
    int length = strlen(s);
    int preLength = 0;     //Record word length
    int curLength = 0;
    while(*s){
        if(*s != ' '){
            curLength++;
            preLength = curLength;
        }

        printf("%d %d\n",curLength,preLength);
        if(*s == ' '){
            curLength = 0;
        }
        s++;
    }
    return preLength;
}

25. Add one

Given a non negative integer represented by a non empty array of integers, add one to the number.

The highest digit is stored in the first place of the array, and each element in the array stores only a single digit.

You can assume that this integer does not start with zero except the integer 0.

Example

Example 1:
	Input: digits = [1,2,3]
	Output:[1,2,4]
	Explanation: the input array represents the number 123.

code

The algorithm starts from the last bit. If the last bit needs to be only after + 1, it will judge in turn. Finally, add 1 space in the result array and reset to complete the calculation.

int* plusOne(int* digits, int digitsSize, int* returnSize)
{
   for(int i=digitsSize-1;i>=0;i--)
   {
       if(digits[i]+1==10)
       {
           digits[i]=0;
       }
       else
       {
           digits[i]=digits[i]+1;
           *returnSize=digitsSize;
           return digits;
       }
   }
    *returnSize=digitsSize+1;
    int *ret=(int*)malloc(sizeof(int)*(digitsSize+1));
    memset(ret,0,sizeof(int)*(digitsSize+1));
    ret[0]=1;
    return ret;
}

answer:

The split method completes the result operation through the merging and splitting of integer numbers. However, due to the limitation of the space size of integers, multiple integer numbers can be considered to complete the operation, which is more troublesome.

int* plusOne(int* digits, int digitsSize, int* returnSize){
    //Convert the number in the array to a real number, that is, integer number merging and splitting
    int i;
    int result = 0;
    for(i = 0;i < digitsSize;i++){
        result += digits[i] * pow(10,digitsSize-i-1);
    }

    //Add number
    result += 1;

    //Judge the number of digits
    int length = 0;
    int temp = result;
    while(temp){
        length++;
        temp /= 10;
    }

    *returnSize = length;
    int * nums = (int *)malloc(sizeof(int) * length);

   //Split number
    for(i = length - 1;i >= 0;i--){
        nums[i] = result % 10;
        result /= 10;
    }
    return nums;
}

26. Square root of x

Give you a nonnegative integer x, calculate and return the square root of X.

Since the return type is an integer, only the integer part will be retained and the decimal part will be rounded off.

Note: it is not allowed to use any built-in exponential functions and operators, such as pow(x, 0.5) or x ** 0.5.

Example

Example 1:
	Input: x = 4
	Output: 2

code

The biggest core of the simulation of square function is the determination of accuracy. For this problem, because it is required to return an integer, the accuracy of the algorithm does not need to be too high. Therefore, we set its accuracy to 0.01 here, and then use the dichotomy for traversal to complete the function simulation.

Where fabs() is a function used to calculate the absolute value of floating-point type data.

int mySqrt(int x){
    //If it is a normal integer
    int i;
    int result = 0;
    //It is special when x = 1. If you do dichotomy here, rounding down can only get 0
    if(x == 1)
        return 1;

    //dichotomy
    double low,high,mid;
    low = 0;
    high = x;

    while(fabs(mid * mid - x) >= 0.01){
        mid = (low + high) / 2.0;

        if(mid * mid - x < 0){
            low = mid;
        } else if(mid * mid - x > 0){
            high = mid;
        }
    }
    result = (int)mid;
    return result;
}

27. Stair climbing problem (classical dynamic programming)

Suppose you are climbing stairs. You need n steps to reach the roof.

You can climb one or two steps at a time. How many different ways can you climb to the roof?

Note: given n is a positive integer.

Example

Example 1:
    Input: 2
    Output: 2
    Explanation: there are two ways to climb to the roof.
    \1.  1 rank + 1 rank
    \2.  2 rank

code

Like the following notes, the algorithm adopts the classical dynamic programming idea, which is also an easy to understand method in multiple problem solutions.

int climbStairs(int n){
    /** Using the idea of dynamic programming
     * f(n) = f(n - 1) + f(n - 2)
     * Compared with the Fibonacci sequence, the climbing method of each layer is the sum of the first two layers
    */
    int step1 = 0,step2 = 0,final = 1;      //final = 1 because f (1) = 1, f (0) = 0 starts from 1
    int i;
    for(i = 1;i <= n;i++){
        step1 = step2;
        step2 = final;
        final = step1 + step2;
    }
    return final;
}

28. Delete duplicate elements in the linked list

There is a linked list arranged in ascending order. Give you the head node of the linked list. Please delete all duplicate elements so that each element appears only once. Returns a linked list of results in the same ascending order.

Example

Example:
	Input: head = [1,1,2]
	Output:[1,2]

code

This problem belongs to the general problem of the linked list. Because it is an orderly situation, only double pointer sliding is needed to ensure the uniqueness of the node element value. In summary, it is to traverse the linked list. It can also be realized by using auxiliary space, but the efficiency of this solution is not high.

struct ListNode* deleteDuplicates(struct ListNode* head){
    //When the linked list is empty
    if (!head) {
        return head;
    }

    //The null pointer problem cannot be in the form of null - > val
    struct ListNode * p = head;
    while (p->next) {
        //If the value of the previous pointer is the same as that of the next pointer, it is deleted    
        if (p->val == p->next->val) {
            struct ListNode * h = p->next;
            p->next = p->next->next;
            free(h);        //Release the linked list node space
        } else 
            p = p->next;
    }

    return head;
}

29. Merge two ordered arrays

You are given two integer arrays nums1 and nums2 in non decreasing order, and two integers m and n representing the number of elements in nums1 and nums2 respectively.

Please merge nums2 into nums1 so that the merged array is also arranged in non decreasing order.

Note: finally, the merged array should not be returned by the function, but stored in the array nums1. In order to deal with this situation, the initial length of nums1 is m + n, where the first m elements represent the elements that should be merged, and the last n elements are 0, which should be ignored. The length of nums2 is n.

Example

Example 1:
    Input: nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
    Output:[1,2,2,3,5,6]
    Explanation: consolidation is required [1,2,3] and [2,5,6] . 
    The combined result is [1,2,2,3,5,6] ,Where bold italics are nums1 Elements in.

code

The algorithm first stores two result arrays in nums1, and then bubble sorting can get the results.

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
    int i,j;
    int totalSize = m + n;
    for(i = 0;i < n;i++){
        nums1[i+m] = nums2[i];   //Continue the assignment from the assigned position
    }

    //Bubble sorting
    for(i = 0;i < totalSize - 1;i++){
        for(j = 0;j < totalSize - i - 1;j++){
            if(nums1[j] > nums1[j+1]){
                int temp = nums1[j];
                nums1[j] = nums1[j+1];
                nums1[j+1] = temp;
            }
        }
    }
}

30. Middle order traversal of binary tree

Given the root node of a binary tree, root, returns its middle order traversal.

Example

Example 3:
	Input: root = [1]
	Output:[1]

code

It mainly uses recursion to complete the middle order traversal. A troublesome point is to store the node traversal data into the array. Here, a user-defined function is used to complete this part.

int* inorderTraversal(struct TreeNode* root, int* returnSize){
    int* res = malloc(sizeof(int) * 501);   //Allocate the maximum space required
    *returnSize = 0;    //Number of data returned
    inorder(root, res, returnSize);
    return res;
}

void inorder(struct TreeNode* root, int* res, int* resSize) {
    //If the node is empty, it will jump out - recursive exit
    if (!root) {
        return;
    }
    inorder(root->left, res, resSize);      //Left recursion
    res[(*resSize)++] = root->val;          //Pass value to result array
    inorder(root->right, res, resSize);     //Right recursion
}

31. Same tree

Give you the root nodes p and q of two binary trees and write a function to check whether the two trees are the same.

If two trees are structurally identical and the nodes have the same value, they are considered to be the same.

Example 1:

**Input: * * p = [1,2,3], q = [1,2,3]

**Output: * * true

answer:

The recursive method is also used, considering that all trees are different, and God and the recursive exit can complete the function recursion.

bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    //Recursive exit - all accesses are completed without false
    if(p==NULL && q==NULL) 
        return true;
    //When p is empty and q is not empty - there will be no case where P and q are not empty at the same time, because it has been considered above
    if(p==NULL||q==NULL) 
        return false;
    //The values of the two nodes are different
    if(p->val != q->val) 
        return false;
    //Left right recursion
    return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);
}

32. Symmetric binary tree

Given a binary tree, check whether it is mirror symmetric.

**Example**

Given a binary tree, check whether it is mirror symmetric.
For example, a binary tree [1,2,2,3,4,4,3] It's symmetrical.

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following one [1,2,2,null,3,null,3] Is not mirror symmetric:

    1
   / \
  2   2
   \   \
   3    3

answer:

The idea of comparing two trees is the same as that in the previous question. Here, we compare whether a tree is mirror symmetric. We can regard the left and right subtrees of the root node of the tree as two trees, and then compare the nodes of the two trees. As long as the conditions or conditions for tree mirror symmetry or asymmetry are given.

//Compare the left and right subtrees of the number of passes. Same empty true: different empty false: different values false - recursion until the comparison is completed
bool Compare(struct TreeNode * p,struct TreeNode* q){
    //Same as null true
    if(p==NULL && q==NULL)
        return true;
    //Different null false
    if(p==NULL || q==NULL)
        return false;
    //Different values false
    if(p->val!=q->val)
        return false;
    return Compare(p->left,q->right) && Compare(p->right,q->left);
}

bool isSymmetric(struct TreeNode* root){
    if(root==NULL)
        return true;
    return Compare(root->left,root->right);
}

33. Maximum depth of binary tree

Given a binary tree, find its maximum depth. The depth of the binary tree is the number of nodes on the longest path from the root node to the farthest leaf node.

Note: leaf nodes refer to nodes without child nodes.

Example

Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

code

The algorithm is relatively simple and mainly uses the idea of recursion. We regard the process of comparing depth as a process of traversing nodes, recursively traverse the left and right subtrees respectively, and add 1 to the depth count of each layer visited. At the same time, we use fmax function to obtain the deepest number as the result return, so as to obtain the maximum depth.

int maxDepth(struct TreeNode* root){
    if(!root)
        return 0;
    
    return fmax(maxDepth(root->left),maxDepth(root->right)) + 1;
}

34. Validate palindrome string

Given a string, verify whether it is a palindrome string. Only alphanumeric characters are considered, and the case of letters can be ignored.

**Note: * * in this question, we define an empty string as a valid palindrome string.

Example

Example 1:
	input: "A man, a plan, a canal: Panama"
	output: true
	Explanation:"amanaplanacanalpanama" It's a palindrome string

code

This question first needs to consider the conditions of ignoring case, spaces, characters and so on. It is allowed to be numbers, that is, it first needs to deal with the string. The processed string is used to judge the relevant palindrome string.

bool isPalindrome(char * s){
    //Processing strings - removing symbols
    int slength = strlen(s);
    char * str = (char *)malloc(sizeof(char) * slength);
    char * temp = str;
    int length = 0;
    while(*s){
        if(*s >= 65 && *s <= 90){
            *str++ = *s + 32;      //Convert to lowercase
            length++;

        } else if(*s >= 97 && *s <= 122){
            *str++ = *s;
            length++;
        } else if(*s >= '0' && *s <= '9'){
            *(str++) = *s;
            length++;
        }
        s++;
    }

    //Determine whether it is a palindrome substring
    int i,tag = 1;
    for(i = 0;i < length;i++){
        if(temp[i] != temp[length - i -1])
            tag = 0;
    }
    if(tag == 1)
        return true;
    else
        return false;

}

35. Figures that appear only once

Given a non empty array of integers, each element appears twice except that one element appears only once. Find the element that appears only once.

Example

Example 1:
	input: [2,2,1]
	output: 1

code

Violence algorithm, through continuous traversal to achieve the elimination effect, the worst-case time complexity is O ( n 2 ) O(n^2) O(n2)

int singleNumber(int* nums, int numsSize){
    // n-square complexity
    int i,j;
    int result = 0;
    for(i = 0;i < numsSize;i++){
        for(j = 0;j < numsSize;j++){
            if(i == j)
                continue;
            if(nums[i] == nums[j]){
                break;
            }
        }
        if(j == numsSize)
            result = nums[i];
    }

    return result;
}

36. Circular linked list (fast and slow pointer)

Example

Given a linked list, judge whether there are links in the linked list.

If there is a node in the linked list that can be reached again by continuously tracking the next pointer, there is a ring in the linked list. In order to represent the rings in a given list, we use the integer pos to represent the position where the tail of the list is connected to the list (the index starts from 0). If pos is - 1, there is no ring in the linked list. Note: pos is not passed as a parameter, but only to identify the actual situation of the linked list.

Returns true if there are links in the linked list. Otherwise, false is returned.

code

This algorithm uses the method of fast and slow pointer. The slow pointer moves slowly and the fast pointer moves fast. If the fast pointer catches up with the slow pointer, there must be a ring, otherwise it does not exist.

bool hasCycle(struct ListNode *head) {
    //Boundary conditions: empty linked list, single node linked list, acyclic
    if (head == NULL || head->next == NULL) {
        return false;
    }

    //Define the fast and slow pointer. The fast pointer moves two steps at a time, and the slow pointer moves one step at a time
    // Why two steps? Because if the two pointers have the same acceleration, that is, the number of moving steps, they remain relatively stationary
    struct ListNode* slow = head;
    struct ListNode* fast = head->next;
    while (slow != fast) {
        //Determine whether the end of the linked list is really reached
        if (fast == NULL || fast->next == NULL) {
            return false;
        }
        slow = slow->next;
        fast = fast->next->next;
    }
    return true;
}

37. Preorder traversal of binary tree (recursion)

Give you the root node of the binary tree, root, and return the preorder traversal of its node value.

Give you the root node of the binary tree, root, and return the preorder traversal of its node value.

Example

Example 1:
    Input: root = [1,null,2,3]
    Output:[1,2,3]
Example 2:
    Input: root = []
    Output:[]
Example 3:
    Input: root = [1]
    Output:[1]

code

Conventional algorithm, recursive implementation. The key point is to store the result data. Two functions are used. One function is used to generate the result array and data, return data and call recursion to traverse, and the other function is used to traverse the binary tree.

int* preorderTraversal(struct TreeNode* root, int* returnSize){
    int* res = malloc(sizeof(int) * 501);   //Allocate the maximum space required
    *returnSize = 0;    //Number of data returned
    inorder(root, res, returnSize);
    return res;
}

void inorder(struct TreeNode* root, int* res, int* resSize) {
    //If the node is empty, it will jump out - recursive exit
    if (!root) {
        return;
    }

    res[(*resSize)++] = root->val;          //Pass value to result array
    inorder(root->left, res, resSize);      //Left recursion
    inorder(root->right, res, resSize);     //Right recursion
}

38. Post order traversal of binary tree (recursion)

Given a binary tree, return its postorder traversal.

Example

Example:
	input: [1,null,2,3]     1    \     2    /   3 
	output: [3,2,1]

answer:

Conventional algorithm, recursive implementation. The key point is to store the result data. Two functions are used. One function is used to generate the result array and data, return data and call recursion to realize traversal, and the other function is used to realize post order traversal of binary tree.

int* postorderTraversal(struct TreeNode* root, int* returnSize){
    int* res = malloc(sizeof(int) * 501);   //Allocate the maximum space required
    *returnSize = 0;    //Number of data returned
    inorder(root, res, returnSize);
    return res;
}

void inorder(struct TreeNode* root, int* res, int* resSize) {
    //If the node is empty, it will jump out - recursive exit
    if (!root) {
        return;
    }
    //Left and right root
    inorder(root->left, res, resSize);      //Left recursion
    inorder(root->right, res, resSize);     //Right recursion
    res[(*resSize)++] = root->val;          //Pass value to result array
}

39. Intersecting linked list

Here are the head nodes headA and headB of the two single linked lists. Please find and return the starting node where the two single linked lists intersect. If two linked lists have no intersection, null is returned.

As shown in the figure, two linked lists intersect at node c1:

The title data ensures that there are no rings in the whole chain structure.

Note that after the function returns the result, the linked list must maintain its original structure.

Custom profiling:

The input of the evaluation system is as follows (the program you designed does not apply to this input):

intersectVal - the value of the starting node of the intersection. If there are no intersecting nodes, this value is 0
listA - first linked list
listB - second linked list
Skip a - the number of nodes that jump to the cross node in listA (starting from the head node)
skipB - the number of nodes that jump to the cross node in listB (starting from the head node)
The evaluation system will create a linked data structure based on these inputs and pass the two head nodes headA and headB to your program. If the program can correctly return the intersection node, your solution will be regarded as the correct answer.

Example

Example 1:
    Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
    Output: Intersected at '8'
    Explanation: the value of intersection node is 8 (note that if two linked lists intersect, it cannot be 0).
    The linked list starts from the respective header A by [4,1,8,4,5],Linked list B by [5,6,1,8,4,5]. 
    stay A In, there are 2 nodes before the intersecting node; stay B In, there are 3 nodes before the intersection node.
Example 2:
    Input: intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
    Output: Intersected at '2'
    Explanation: the value of intersection node is 2 (note that if two linked lists intersect, it cannot be 0).
    The linked list starts from the respective header A by [1,9,1,2,4],Linked list B by [3,2,4]. 
    stay A In, there are 3 nodes before the intersection node; stay B In, there is 1 node before the intersection node.

code

The problem still adopts the violence method. Select a linked list as the main list and a linked list as the sub list. The main table performs an outer loop, and the sub table performs an inner loop. The outer pointer is + 1 each time, and the inner layer traverses the whole table for comparison. If the values of even two pointers are the same, there is an intersection and the result is returned; Otherwise, NULL is returned.

struct ListNode * getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    //Violence law
    //Both loop traversal
    struct ListNode * p,* q;
    p = headA;
    //The outer layer is headA cycle 1 - size times
    while(p){
        //Loop sizeA * (1 - sizeB) with inner layer of headB
        q = headB;
        while(q){
            if(p == q){
                return p;
            }
            q = q->next;
        }
        p = p->next;
    }
    return NULL;
}

40. Excel table column name (hexadecimal conversion algorithm)

Example

Give you an integer columnNumber ,Return it in Excel The name of the corresponding column in the table.
For example:
A -> 1 B -> 2 C -> 3 ... Z -> 26 AA -> 27 AB -> 28 

code

The idea of the algorithm is to borrow the bit segmentation of integers, that is, to change the subject as the conversion of 10 - > 26 hexadecimal numbers, divide the converted 26 hexadecimal bits, and then convert them into corresponding strings to complete the result.

void reverse(char* str, int strSize) {
    int left = 0, right = strSize - 1;
    while (left < right) {
        char tmp = str[left];
        str[left] = str[right], str[right] = tmp;
        left++;
        right--;
    }
}

char* convertToTitle(int columnNumber) {
    char* ans = malloc(sizeof(char) * 8);
    int ansSize = 0;

    while (columnNumber > 0) {
        --columnNumber;
        ans[ansSize++] = columnNumber % 26 + 'A';
        columnNumber /= 26;
    }
    ans[ansSize] = '\0';
    reverse(ans, ansSize);
    return ans;
}

41. Most elements

Given an array of size n, find most of its elements. Most elements refer to elements that appear more than ⌊ n/2 ⌋ in the array.

You can assume that the array is non empty and that there are always many elements in a given array.

Example

Example 1:
	Input:[3,2,3]
	Output: 3

code

Ingenious solution (Moore voting):

In analogy with voting, the number of votes for one person is + 1 and the number of votes for another person is - 1. The result will be returned only when the number of votes for one person exceeds n/2, which is also the cleverness of the algorithm.

int majorityElement(int* nums, int numsSize){
     int * stack=malloc(sizeof(int)*numsSize);      //Generates an array of numsize sizes
     int top=-1;
     for(int i=0;i<numsSize;i++){
         if(top==-1){
             stack[++top]=nums[i];
         }
         else if(stack[top]==nums[i]){
             stack[++top]=nums[i];
         }
         else top--;
     }
     return stack[0];
}

Violent solution:

O(n`2) you can get an ordered sorting sequence by sorting first. The same elements are always next to each other. Now we only need to consider finding the elements that appear the most times. Here, the idea of double pointers is used to traverse for the maximum number of times.

Optimization - you can consider using a higher performance sorting algorithm, where the maximum number of occurrences is calculated- Can be optimized to O(nlogN)

In addition, we can use the idea of double pointers directly, that is, the number of times to find one element at a time.

int majorityElement(int* nums, int numsSize){
    //O(n`2) algorithm
    //Bubble sorting
    int i,j;
    for(i = 0;i < numsSize;i++){
        for(j = 0;j < numsSize - i - 1;j++){
            if(nums[j] > nums[j+1]){
                int temp = nums[j];
                nums[j] = nums[j+1];
                nums[j+1] = temp; 
            }
        }
    }

    //The current values are ordered, so the idea of double pointers is used here. max saves the maximum value and cur saves the currently stored value
    int maxValue = 0,maxTimes = 0;
    int curValue = nums[0],curTimes = 0;
    for(i = 0;i < numsSize;i++){
        if(curValue == nums[i]){
            curTimes++;     //Number of occurrences + 1
            continue;
        }

        if(maxTimes < curTimes){
            maxValue = curValue;
            maxTimes = curTimes;
        }
        //Updates the value of the current pointing variable
        curValue = nums[i];
        curTimes = 1;
    }

        if(maxTimes < curTimes){
            maxValue = curValue;
            maxTimes = curTimes;
        }

    return maxValue;
}

42. Combine two tables (SQL)

Table 1: Person
+-------------+---------+
| Listing         | type     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId Is the primary key of the previous table
 Table 2: Address
+-------------+---------+
| Listing         | type    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId Is the primary key of the previous table

Write an SQL query that meets the following conditions: whether a person has address information or not, the following information of a person needs to be provided based on the above two tables:

FirstName, LastName, City, State

Solution:

Because you want to get the information of the two tables, and the City and State are on the right, use the left join to link the two tables.

select FirstName, LastName , City, State
from Person left join Address
on Person.PersonId = Address.PersonId;

43. Find employees with higher salary than managers (SQL)

SQL framework
Employee The table contains all employees, and their managers belong to employees. Every employee has one Id,In addition, there is a list of managers corresponding to employees Id. 

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+
given Employee Table, write a SQL Query, which can get the names of employees whose income exceeds their managers. In the table above, Joe Is the only employee who earns more than his manager.

+----------+
| Employee |
+----------+
| Joe      |
+----------+

Solution:

Since you want to get employees who exceed the manager's salary on a table, you need to use a double-layer cycle. Here, the header is defined as "employee" outer layer a and inner layer b. when the manager number of employee a is equal to the number of b and the salary of employee a is greater than that of b (Manager), the result will be returned.

SELECT 
    a.Name AS 'Employee'
FROM
    Employee AS a,
    Employee AS b
WHERE
    a.ManagerId = b.Id AND a.Salary > b.Salary;

44. Find duplicate email addresses (SQL)

Write an SQL query to find all duplicate e-mail addresses in the Person table.

Write a SQL Query, find Person All duplicate email addresses in the table.

Example:

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+
Based on the above input, your query should return the following results:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

code

SELECT DISTINCT 
    a.Email AS 'Email' 
FROM 
    Person AS a,
    Person AS b
WHERE 
    a.Email = b.Email AND a.Id != b.Id;

45. Customers who never order (SQL)

A website contains two tables, the Customers table and the Orders table. Write an SQL query to find all Customers who never order anything.

A website contains two tables, Customers Table and Orders Watch. Write a SQL Query to find all customers who never order anything.
Customers Table:
+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+
Orders Table:

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+
For example, given the above table, your query should return:

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

code

Not in keyword is used to judge the data that is not in the query result

select customers.name as 'Customers' 
from customers 
where customers.id not in (  
		select customerid from orders 
);


The brush notes are completely coded in C language, with 3 questions a day. Of course, this is what I ask myself. Due to other force majeure factors such as business or rest, the upload may be delayed, that is this day matter bright day Finish − circle rise come this in want Test Finish today's work tomorrow. - circle it here for the exam Finish today's work tomorrow − circle it here for the exam. All codes are uploaded to gitee synchronously Warehouse link.
To be honest, it's very difficult to brush questions in pure C language. There are few wheels available, but it's also very exercise. Don't feel too good making your own wheels. My goal is to finish all LeetCode question banks in a few years. According to the current update, 2500 may take about 3 years. I hope I can stick to it and come on.

Posted by jauson on Tue, 30 Nov 2021 03:53:26 -0800