万人千题第一阶段报告【待继续总结】

学习内容概况

目的:找编程和做题的手感

具体训练内容万人千题第一阶段题库(思维导图),同时还有一些之前做过的题

在这里插入图片描述
题目大纲

练习后总结

具体细节之后补充为文字版,概况思维导图如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

编程细节

  • 位运算使用技巧
    • data<<1 = data*2data>>1 = data / 2左移右移等于乘除2
    • data & 1可以判断是否为奇数
    • data & (1<<i)可以判断第i位是否为1

库函数适当使用

qsort

排序内容必须是数组

原型:

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

在这里插入图片描述

代码案例:

  • 一维数组:
    • /* qsort example */
      #include <stdio.h>      /* printf */
      #include <stdlib.h>     /* qsort */
      
      int values[] = { 40, 10, 100, 90, 20, 25 };
      
      int compare (const void * a, const void * b)
      {
        return ( *(int*)a - *(int*)b );
      }
      
      int main ()
      {
        int n;
        qsort (values, 6, sizeof(int), compare);
        for (n=0; n<6; n++)
           printf ("%d ",values[n]);
        return 0;
      }
      
  • 二维数组:
    • #include <stdio.h>      /* printf */
      #include <stdlib.h>     /* qsort */
      
      int cmp(const void *a,const void *b)
      {
          int *ap = *(int **)a;   
          int *bp = *(int **)b;
      
          if(ap[0] == bp[0])
              return ap[1] - bp[1];
          else
              return ap[0] - bp[0];
      } 
      
      int cmp(const void *a, const void *b)
      {
          return ((int *)a)[0] - ((int *)b)[0];
      }
      
      int main(){
          int *b,**a;
          int n = 10;
          a = (int**)malloc(n*sizeof(int*));for(i=0;i<n;i++)
          {
              b = malloc(2*sizeof(int));
              a[i] = b;
          }
      
          int c[10][2] = {0};
          //赋值c
      
          qsort(a, n, sizeof(a[0]), cmp);
          qsort(c, n, sizeof(c[0]), cmp);
      
          for(i=0;i<n;i++) 
          { 
                free(a[i]);
          }
          free(a);
      }
      
  • 结构体排序:
    • /* qsort example */
      #include <stdio.h>      /* printf */
      #include <stdlib.h>     /* qsort */
      
      typedef struct node{
          int x;  
          int y;  
          int z;  
      }Node;
      
      //-> is prioer than (type)
      int cmp(const void *a, const void *b)
      {
      //    return (Node *)a->x - (Node *)b->x;   //wrong!
      //    return ((Node *)a)->x - ((Node *)b)->x;   //wrong!
          return (*(Node *)a).x - (*(Node *)b).x;     //right
      }
      
      int main ()
      {
          // get many Node things.
          qsort(a, n, sizeof(a[0]), cmp);
      }
      

解题模板

尽量通过总结和理解,将题目抽象为一类题目,并构建基础编程模板

看了题解的问题

解答汇总

编写的代码遵循以下规范:

  1. 代码使用C语言进行编写
  2. 代码尽量通过合适的变量名等方式提高可读性
  3. 尽量做到不使用注释能立马反应代码含义
  4. 代码中保留在LeetCode上调试代码的关键输出语句,不影响提交通过结果。

基础语法&数据处理&数据结构

位运算

136. 只出现一次的数字
int singleNumber(int* nums, int numsSize){
    int res = 0;

    while (numsSize--) {
        printf("%d ",numsSize);
        res ^= nums[numsSize];
    }

    return res;
}
面试题 16.01. 交换数字
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* swapNumbers(int* numbers, int numbersSize, int* returnSize){
    *returnSize = numbersSize;

    int *res = (int *)malloc(sizeof(int)*2);

    res[0] = numbers[0] ^ numbers[1];
    res[1] = numbers[1] ^ res[0];
    res[0] = res[1] ^ res[0];

    return res;
} 
191. 位1的个数
int hammingWeight(uint32_t n) {
    int res =0;

    while (n) {
        res += n & 1;
        n >>= 1;
    }

    return res;
}

int hammingWeight(uint32_t n) {
    int res =0;

    while (n) {
        n &= n - 1;
        printf("%d ",n);
        res++;
    }

    return res;
}
1486. 数组异或操作
int xorOperation(int n, int start){
    int res = start;

    while (n--) {
        int num = start + 2 * n;
        res ^= num;
    } 

    return res ^ start;
}
1720. 解码异或后的数组
201. 数字范围按位与
int rangeBitwiseAnd(int left, int right){
    int t = 0;
    while (left != right) {
        left >>= 1;
        right >>= 1;
        t++;
    }

    return left << t;
}
剑指 Offer 64. 求1+2+…+n
int sumNums(int n){
    int A = n;
    int B = n + 1;
    int ans = 0;
  
    //当b为偶数,a*b=2a * b/2;当n为奇数,a*b=(b-1)/2 * 2a+a
    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    (B & 1) && (ans += A);
    A <<= 1;
    B >>= 1;

    return ans >> 1;

}

理解整数型

1281. 整数的各位积和之差
int subtractProductAndSum(int n){
    int mul = 1;
    int sum = 0;
    int num = 0;

    while (n) {
        num = n%10;
        mul *= num;
        sum += num;

        n /=10;
    }

    return mul - sum;
}
1290. 二进制链表转整数
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


int getDecimalValue(struct ListNode* head){
    struct ListNode *pNode = head;
    int sum = 0;

    while (pNode) {
        sum = sum * 2 + pNode->val;
        pNode = pNode->next;
    }

    return sum;
}
1342. 将数字变成 0 的操作次数
int numberOfSteps(int num){
    int res = 0;

    while (num) {
        if (num & 1) {
            res++;
            num--;
            continue;
        }
        res++;
        num >>= 1;
    }

    return res;
}
1480. 一维数组的动态和
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* runningSum(int* nums, int numsSize, int* returnSize){
    *returnSize = numsSize;
    int *res = (int *) malloc(sizeof(int) * numsSize);

    int i = 1;
    res[0] = nums[0];
    while (i < numsSize) {
        res[i] = res[i - 1] + nums[i];
        i++;
    }

    return res;
}
628. 三个数的最大乘积
int cmp(int *a, int *b) {
    return *a - *b;
}

int maximumProduct(int* nums, int numsSize){
    qsort(nums, numsSize, sizeof(int), cmp);

    int res = (nums[numsSize-1] * nums[numsSize - 2] * nums[numsSize - 3]) > 
            (nums[0] * nums[1] *nums[numsSize - 1]) ?
            (nums[numsSize-1] * nums[numsSize - 2] * nums[numsSize - 3]) :
            (nums[0] * nums[1] *nums[numsSize - 1]);

    return res;
}
1588. 所有奇数长度子数组的和
int sumOddLengthSubarrays(int* arr, int arrSize){
    int res = 0;
    int left = 0;
    int right = 0;
    int sum = 0;

    while (left < arrSize){
        sum += arr[right++];
  
        if (((right - left) & 1)) {
            res += sum;
        }

        if (right >= arrSize) {
            left++;
            right = left;
            sum = 0;
        } 
    }

    return res;
}
485. 最大连续 1 的个数
int findMaxConsecutiveOnes(int* nums, int numsSize){
    int cnt = 0;
    int res = 0;
  
    for (int i = 0; i < numsSize ; i++) {
        res = cnt > res ? cnt : res;
        cnt = cnt * nums[i] + nums[i]; 
    }

    return cnt > res ? cnt : res; 
}
1822. 数组元素积的符号
int signFunc(int x) {
    return x > 0 ? 1 : -1;
}
int arraySign(int* nums, int numsSize){
    int mul = 1;

    while (numsSize--) {
        if (nums[numsSize] == 0)
            return 0;
        if (nums[numsSize] < 0)
            mul *= (-1);
    }

    return mul;
}
1295. 统计位数为偶数的数字
int findNumbers(int* nums, int numsSize){
    int res = 0;

    while (numsSize--) {
        int cnt = 1;
        int num = nums[numsSize];

        while (num/=10) {
            cnt++;
        }

        if (cnt & 1) {
            continue;
        }
        res++;
    }

    return res;
}
剑指 Offer 17. 打印从1到最大的n位数
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* printNumbers(int n, int* returnSize){
    int size =  0;
    while (n) {
        size = size * 10 + 9;
        n--;
    }
    *returnSize = size;

    int *res = (int *) malloc(sizeof(int) * size);
    while (size--) {
        res[size] = size + 1;
    }

    return res;
}
剑指 Offer II 003. 前 n 个数字二进制中 1 的个数
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* countBits(int n, int* returnSize){
    int *res = (int *)malloc(sizeof(int) * (n + 1));
    *returnSize = n + 1;
    res[0] = 0;

    for (int i = 0; i <= n; i++) {
        res[i] = res[i >> 1] + (i & 1);
    }

    return res;
}

字符串?

344. 反转字符串
void reverseString(char* s, int sSize){
    for (int i = 0; i < sSize/2; i++) {
        s[i] ^= s[sSize - 1 - i];
        s[sSize - 1 - i] ^= s[i];
        s[i] ^= s[sSize - 1 - i];
    }
}
1662. 检查两个字符串数组是否相等
bool arrayStringsAreEqual(char ** word1, int word1Size, char ** word2, int word2Size){
    int w1 = 0;
    int w2 = 0;
    int c1 = 0;
    int c2 = 0;


    while (w1 < word1Size && w2 < word2Size) {
        int flag = 0;
        if (word1[w1][c1] == '\0') {
            w1++;
            c1 = 0;
            flag = 1;
        } 
    
        if (word2[w2][c2] == '\0') {
            w2++;
            c2 = 0;
            flag = 1;
        }

        if (flag) {
            continue;
        }

        char ch1 = word1[w1][c1++];
        char ch2 = word2[w2][c2++];

        if (ch1 != ch2) {
            return false;
        }
    }

    if ((w1 != word1Size) || (w2 != word2Size)) {
        return false;
    }

    return true;
}
1832. 判断句子是否为全字母句
bool checkIfPangram(char * sentence){
    int hash[26] = {0};
    int len = strlen(sentence);

    while (len--) {
        hash[sentence[len] - 'a']++;
    }

    for (int i = 0; i < 26; i++) {
        if (hash[i] == 0) {
            return false;
        }
    }
  
    return true;
}
1684. 统计一致字符串的数目
int countConsistentStrings(char * allowed, char ** words, int wordsSize){
    int res = 0;
    int hash[26] = {0};
    int len = strlen(allowed);

    while (len--) {
        hash[allowed[len] - 'a']++;
    }

    while (wordsSize--) {
        char *tmp = words[wordsSize];
        len = strlen(tmp);
        while(len--) {
            if (!hash[tmp[len] - 'a']) {
                break;
            }
        }
  
        if (len == -1) {
            res++;
        }
    }
  
    return res;
}
771. 宝石与石头
int getIndx(char x) {
    return x - 'A' > 26 ? x - 'a' + 26 : x - 'A';
}

int numJewelsInStones(char * jewels, char * stones){
    int numj = strlen(jewels);
    int nums = strlen(stones);
    int hash[54] = {0};
    int res = 0;

    while (nums--) {
        int idx = getIndx(stones[nums]);
        hash[idx]++;
    }

    while (numj--) {
        int idx = getIndx(jewels[numj]);
        res += hash[idx];
        hash[idx] = 0;
    }

    return res;
}
2011. 执行操作后的变量值
int finalValueAfterOperations(char ** operations, int operationsSize){
    int res = 0;

    while (operationsSize--) {
        operations[operationsSize][1] == '-' ?
            res-- : res++;
    }

    return res;
}
剑指 Offer 58 - II. 左旋转字符串
char* reverseLeftWords(char* s, int n){
    int len = strlen(s);
    char *res = (char *)malloc(sizeof(char) * (len + 1));
    res[len] = '\0';

    for (int i = 0; i < len - n; i++) {
        res[i] = s[n + i];
    }

    for (int i = 0; i < n; i++) {
        res[len - n + i] = s[i];
    }

    return res;
}
面试题 01.01. 判定字符是否唯一
面试题 01.02. 判定是否互为字符重排
383. 赎金信
537. 复数乘法
void getVal (char *num, int *real1, int *virt1) {
    int flag = 0;
    int real = 0;
    int virt = 0;
    int minus = 1;
    int len = strlen(num);

    for (int i = 0; i < len; i++) {
        if (num[i] == '+') {
            flag = 1;
            continue;
        }

        if (i > 0 && num[i] == '-') {
            flag = -1;
            continue;
        } else if (num[i] == '-'){
            minus = -1;
            continue;
        }

        if (num[i] == 'i') {
            break;
        }

        if (!flag) {
            real = real * 10 + (num[i] - '0');
        } else {
            virt = virt * 10 + (num[i] - '0');
        }
    }
    virt *=flag;
    real *=minus;
    printf("%d,%d", real, virt);
    *real1 = real;
    *virt1 = virt;
}

char * complexNumberMultiply(char * num1, char * num2){
    int real1 = 0;
    int real2 = 0;
    int real = 0;
    int virt1 = 0;
    int virt2 = 0;
    int virt = 0; 

    getVal (num1, &real1, &virt1);
    getVal (num2,&real2, &virt2);

    real = real1 * real2 - virt1 * virt2;
    virt = real1 * virt2 + real2 * virt1;

    char *res = (char *)malloc(sizeof(char) * 20);
    sprintf(res, "%d+%di", real, virt);
    return res;
}
1108. IP 地址无效化
char * defangIPaddr(char * address){
    int len = strlen (address);
    int newLen = len + 6;
    char *res = (char *)malloc(sizeof(char) * newLen + 1);
    res[newLen] = '\0';

    while (len--) {
        if (address[len] == '.') {
            res[newLen-1] = ']';
            res[newLen-2] = '.';
            res[newLen-3] = '[';
            newLen -= 3;
            continue;
        }

        res[newLen - 1] = address[len];
        newLen--;
    }

    return res;
}

基础数学

1925. 统计平方和三元组的数目
int countTriples(int n){
    int a = 2;
    int b = 3;
    int res = 0;

    for (a = 1; a < n; a++) {
        for (b = 1; b < n; b++) {
            int c = (int)sqrt(a * a + b * b + 1);
            if (c <= n && (c * c == a * a + b * b)) {
                res++;
            }
        }
    }

    return res;
}
2006. 差的绝对值为 K 的数对数目
int countKDifference(int* nums, int numsSize, int k){
    int res = 0;

    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            int judge = abs(nums[i] - nums[j]);

            if (judge == k) {
                res++;
            }
        }
    }
  
    return res;
}
1979. 找出数组的最大公约数
int findGCD(int* nums, int numsSize){
    int max = nums[0];
    int min = nums[0];
    int res = 1;

    for (int i = 1; i < numsSize; i++) {
        max = max > nums[i] ? max : nums[i];
        min = min < nums[i] ? min : nums[i];
    }

    return gcd (max, min);
}
1492. n 的第 k 个因子
int kthFactor(int n, int k){
    int *elem = (int*) malloc(sizeof(int)*k);
    int idx = 0;

    for(int i = 1; i <= n && idx < k; i++) {
        if (n % i == 0) {
            elem[idx++] = i;
        }
    }

    return idx < k ? -1 : elem[k-1];
}
剑指 Offer 57 - II. 和为s的连续正数序列
int** findContinuousSequence(int target, int* returnSize, int** returnColumnSizes) {
    if (target < 2) {
        return NULL;
    }
    int maxSize = (target + 1) / 2;
    int** res = (int**)malloc(sizeof(int*) * maxSize);
    *returnColumnSizes = (int*)malloc(sizeof(int) * maxSize);
    int sizes = *returnColumnSizes;
    int cnt = 0;
    int i = 1;
    int j = i;
    int size = 1;
    int sum = 0;
  
    while (i < maxSize) {
        if (sum < target) {
            sum += j++;
            size++;
        }

        if (sum > target) {
            sum -= i++;
            size--;
        }

        if (sum == target) {
            (*returnColumnSizes)[cnt] = size - 1;
            res[cnt] = (int*)malloc(sizeof(int) * (size - 1));
            for (int z = 0; z < size - 1; z++) {
                res[cnt][z] = i + z;
            }
            cnt++;
            sum -= i++;
            size--;
        }
    }

    *returnSize = cnt;
    return res;
}
面试题 08.05. 递归乘法
void swap(int *A, int *B) {
    int t = *A;

    if (*A < *B) {
        *A = *B;
        *B = t;
    }
}

int multiply(int A, int B){
    int sum = 0;

    swap(&A, &B);

    while(B) {
        if (B & 1) {
            sum += A;
        }
        B >>= 1;
        if (B) A <<= 1;
    }

    return sum;
}
509. 斐波那契数
int fib(int n){
    int f0 = 0;
    int f1 = 1;
    int fn = f0 + f1;

    while (n > 1) {
        fn = f0 + f1;
        f0 = f1;
        f1 = fn;
        n--;
    }

    if (n < 1) return f0;

    return fn;
}
812. 最大三角形面积
double area(int* P, int* Q, int* R) {
    return 0.5 * abs(P[0] * Q[1] + Q[0] * R[1] + R[0] * P[1]
                            -P[1] * Q[0] - Q[1] * R[0] - R[1] * P[0]);
}

double largestTriangleArea(int** points, int pointsSize, int* pointsColSize){
    double res = 0;

    for (int i= 0; i < pointsSize - 2; i++) {
        for (int j = i + 1; j < pointsSize - 1 ; j++) {
            for (int z = j + 1; z < pointsSize; z++) {
                double size = area (points[i], points[j], points[z]);
                res = res >  size? res : size;
            }
        }
    }
  
    return res;
}

进制理解与运算

504. 七进制数
char * convertToBase7(int num){
    int resDec = 0;
    int ifMinus = num >= 0 ? 0 : 1;
    num = abs(num);
    int cnt = 0;
    int cal = num;

    if (num == 0) {
        cnt = 1;
    }
    while (cal) {
        cal /= 7;
        cnt++;
    }

    cnt = cnt + ifMinus + 1;
    char *res = (char *) malloc(sizeof(char) * (cnt--));
    if (ifMinus) {
        res[0] = '-';
    }
    res[cnt--] = '\0';

    while (cnt >= ifMinus) {
        res[cnt--] = '0' + num % 7;
        printf("%d", cnt + 1);
        num /= 7;
    }

    return res;
}
405. 数字转换为十六进制数
char getHexChar(int num) {
    switch (num) {
        case 0:
            return '0';
        case 1:
            return '1';
        case 2:
            return '2';
        case 3:
            return '3';
        case 4:
            return '4';
        case 5:
            return '5';
        case 6:
            return '6';
        case 7:
            return '7';
        case 8:
            return '8';
        case 9:
            return '9';
        case 10:
            return 'a';
        case 11:
            return 'b';
        case 12:
            return 'c';
        case 13:
            return 'd';
        case 14:
            return 'e';
        case 15:
            return 'f';
    }
    return '0';
}

char * toHex(int num){
    char *res = (char*)malloc(sizeof(char) * 9);
    unsigned int cal = (unsigned int) num;

    if (num == 0) {
        res[0] = '0';
        res[1] = '\0';
        return res;
    }

    int idx = 0;
    while (cal) {
        idx++;
        cal /= 16;
    }

    cal = (unsigned int) num;
    res[idx] = '\0';
    while (idx--) {
        res[idx] = getHexChar(cal % 16);
        cal /= 16;
    }
  
    return res;
}
1837. K 进制表示下的各位数字总和
int sumBase(int n, int k){
    int res = 0;

    while (n) {
        res += n%k;
        n /= k;
    }

    return res;
}
190. 颠倒二进制位
uint32_t reverseBits(uint32_t n) {
    uint32_t res = 0;
    uint32_t t = (uint32_t)(-1);

    while (t) {
        res = (res << 1) + (n & 1);
        n >>= 1;
        t >>= 1;
    }

    return res;
}
258. 各位相加
int addDigits(int num){
    int res = 0;

    while (num) {
        res += num % 10;
        num = num / 10;

        if (!num && res / 10) {
            num = res;
            res = 0;
        }
    }

    return res;
}

理解数组

860. 柠檬水找零
1512. 好数对的数目
int numIdenticalPairs(int* nums, int numsSize){
    int res = 0;

    for (int i = 0; i < numsSize; i++) {
        for (int j = i + 1; j < numsSize; j++) {
            if (nums[i] == nums[j]) {
                res++;
            }
        }
    }

    return res;
}
217. 存在重复元素
int cmp(int *a, int *b){
    return *a - *b;
}

bool containsDuplicate(int* nums, int numsSize){
    qsort(nums, numsSize, sizeof(int), cmp);

    for(int i = 0; i < numsSize - 1; i++) {
        if (nums[i] == nums[i + 1]) {
            return true;
        }
    }

    return false;
}
27. 移除元素
int removeElement(int* nums, int numsSize, int val){
    int newIdx = 0;
    int idx = 0;

    for(; idx < numsSize; idx++) {
        if (nums[idx] == val) {
            continue;
        }

        if (nums[idx] != val) {
            nums[newIdx++] = nums[idx];
        }
    }

    return newIdx;
}
26. 删除有序数组中的重复项
int removeDuplicates(int* nums, int numsSize){
    int fast = 1;
    int slow = 0;
    if(numsSize <= 1) {
        return numsSize;
    }

    for (; fast < numsSize; fast++) {
        if (nums[fast] != nums[fast -1]) {
            nums[slow + 1] = nums[fast];
            slow++;
        }
    }
  
    return slow + 1;
}
1863. 找出所有子集的异或总和再求和
int subsetXORSum(int* nums, int numsSize){
    int res = 0;
    int xor = 0;

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

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

    return res;
}
1365. 有多少小于当前数字的数字
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize){
    int *res = (int *)malloc(sizeof(int) * numsSize);
    memset(res, 0, sizeof(int) * numsSize);
    *returnSize = numsSize;

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

    for (int i = 0; i < numsSize; i++) {
        int val = nums[i];
        while (val--) {
            res[i] += hash[val];
        }
    }

    return res;
}
1929. 数组串联
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* getConcatenation(int* nums, int numsSize, int* returnSize){
    int len = numsSize;
    *returnSize = 2 * len;
    int *res = (int *) malloc(sizeof(int) * 2 * len);

    while(len--) {
        res[len] = nums[len];
        res[len + numsSize] = nums[len];
    }

    return res;
}
1464. 数组中两元素的最大乘积
int maxProduct(int* nums, int numsSize){
    int biggest;
    int second;
    int i;

    if (numsSize < 2) {
        return 0;
    }
    biggest = nums[0] > nums[1] ? nums[0] : nums[1];
    second = nums[0] > nums[1] ? nums[1] : nums[0];

    for (i = 2; i < numsSize ; i++) {
        if (nums[i] > biggest) {
            second = biggest;
            biggest = nums[i];
        } else if (nums[i] > second) {
            second = nums[i];
        }
    }

    return (biggest-1) * (second-1);
}
414. 第三大的数
//堆排序
void swap(int *nums,int i,int j){
    int t=nums[i];
    nums[i]=nums[j];
    nums[j]=t;
}
void MaxHeapify(int *nums,int index,int numsSize){      //维护大根堆
    int lchild=2*index,rchild=2*index+1;
    int max=index;                                 
    if(lchild<numsSize&&nums[lchild]>nums[max])
        max=lchild;
    if(rchild<numsSize&&nums[rchild]>nums[max])
        max=rchild;
    if(index!=max){
        swap(nums,index,max);
        MaxHeapify(nums,max,numsSize);
    }
}
void MaxHeap(int *nums,int numsSize){       //建堆
    for(int i=numsSize/2;i>=0;i--){
        MaxHeapify(nums,i,numsSize);
    }
}
int thirdMax(int* nums, int numsSize){
    MaxHeap(nums,numsSize);             //建堆
    int count=1,ans=nums[0],size=numsSize;
    int max=ans;
    while(count<3){
        swap(nums,0,size-1);
        --size;
        if(size<1)
            return max;     //不够3次
        MaxHeapify(nums,0,size);    //维护大根堆
        if(ans!=nums[0]){
            ++count;
            ans=nums[0];
        }else{
            continue;
        }
    }
    return nums[0];
}

链表の本质

面试题 02.03. 删除中间节点
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
void deleteNode(struct ListNode* node) {
    struct ListNode* del = node->next;
    node->val = node->next->val;
    node->next = node->next->next;
    free(del);
}
剑指 Offer 18. 删除链表的节点
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteNode(struct ListNode* head, int val){
    struct ListNode *dumHead = (struct ListNode *)malloc(sizeof(struct ListNode));
    dumHead->next = head;
    struct ListNode *pre = head;
    struct ListNode *later = dumHead;

    while (pre) {
        if (pre->val == val) {
            later->next = pre->next;
            break;
        }
        pre = pre->next;
        later = later->next;
    }

    free(pre);

    return dumHead->next;
}

树の递归理解

144. 二叉树的前序遍历
94. 二叉树的中序遍历
589. N 叉树的前序遍历
LCP 44. 开幕式焰火
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
int dfs (int res, int * hash, struct TreeNode* root) {
    if (!root) {
        return res;
    }

    if (hash[root->val] == 0) {
        //printf("%d ", hash[root->val]);
        hash[root->val] = 1;
        ++res;
    }

    res = dfs(res, hash, root -> left);
    res = dfs(res, hash, root -> right);

    return res;
}

int numColor(struct TreeNode* root){   
    int res = 0;
    int hash[1001] = {0};

    res = dfs(res, hash, root);

    return res;
}
剑指 Offer 27. 二叉树的镜像
剑指 Offer 55 - I. 二叉树的深度
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */


int maxDepth(struct TreeNode* root){
    if (!root) {
        return 0;
    }

    return fmax(maxDepth(root -> left), maxDepth(root -> right)) + 1;
}
剑指 Offer 55 - II. 平衡二叉树

基础算法&思维

查找

剑指 Offer 04. 二维数组中的查找
33. 搜索旋转排序数组
int search(int* nums, int numsSize, int target){
    int res;
    int left = 0;
    int right = numsSize - 1;
    int mid = (left + right) / 2;

    while (left <= right) {
        printf ("%d, %d, %d\n", left, mid, right);
        if (nums[mid] == target) {
            return mid;
        }

        if (nums[left] == target) {
            return left;
        }

        if (nums[right] == target) {
            return right;
        }

        // left is a sorted array
        if (nums[left] < nums[mid]) {
            if (nums[mid] < target) {
                left = mid + 1;
                right -=1;
            } else {
                left += 1;
                right -=1;
            }
        } else {
        // right is sorted
            if (nums[mid] > target) {
                left += 1;
                right = mid - 1;
            } else {
                left += 1;
                right -=1;
            }
        }
        mid = (left + right) / 2;
    }

    return -1;
}
153. 寻找旋转排序数组中的最小值
int findMin(int* nums, int numsSize){
    int left = 0;
    int right = numsSize - 1;
    int mid = (left + right) / 2;

    do {
        ///< when the graph is like ^V
        if (nums[left] > nums[right]) {
            ///< narrow the border, follow the trend
            left = nums[mid] > nums[left] ? mid : left;
            right = nums[mid] < nums[right] ? mid : right;
            mid = (left + right) / 2;
        } else { ///< is like A
            return nums[left];
        } 
    } while (1 != (right - left)) ;

    ///< is like V 
    return nums[right];
}
int search(int* nums, int numsSize, int target){
    int left = 0;
    int right = numsSize - 1;
    int mid = (left + right) / 2;

    if (numsSize == 1) {
        return (nums[0] == target) ? 0 : -1;
    }

    while (left <= right) {
        if (nums[mid] == target) {
            return mid;
        }
        if (nums[left] == target) {
            return left;
        }

        if (nums[right] == target) {
            return right;
        }

        if (nums[left] < nums[mid]) {
            if (nums[left] < target && nums[mid] > target) {
                left = left + 1;
                right = mid - 1;
            } else {
                left = mid + 1;
                right = right - 1;
            }
        } else {
            if (nums[mid + 1] <= target && nums[right] > target) {
                left = mid + 1;
                right = right - 1;
            } else {
                left = left + 1;
                right = mid - 1;
            }
        }
    
        mid = (left + right) / 2;
    }

    return -1;
}
1302. 层数最深叶子节点的和
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
//int sum;
//int depth;
void dfs(struct TreeNode* root, int cur_depth, int max, int *sum)
{
    if (root == NULL){
        return;
    }

    if ((root->left == NULL) && (root->right == NULL) && (cur_depth == max)) {
        *sum += root->val;
    }
    dfs(root->left, cur_depth + 1, max, sum);
    dfs(root->right, cur_depth + 1, max, sum);
}
int maxDepth(struct TreeNode* root) {
    if (!root){
        return 0;  
    }
    return 1 + fmax(maxDepth(root->left), maxDepth(root->right));
}

int deepestLeavesSum(struct TreeNode* root){
    int sum = 0;
    int max = maxDepth(root);

    dfs(root, 1, max, &sum);
    return sum;
}
剑指 Offer 11. 旋转数组的最小数字
int minArray(int* numbers, int numbersSize){
    int low = 0;
    int high = numbersSize - 1;
    while (low < high) {
        int pivot = low + (high - low) / 2;
        if (numbers[pivot] < numbers[high]) {
            high = pivot;
        } else if (numbers[pivot] > numbers[high]) {
            low = pivot + 1;
        } else {
            high -= 1;
        }
    }
    return numbers[low];
}
41. 缺失的第一个正数
int firstMissingPositive(int* nums, int numsSize){
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] <= 0) {
            nums[i] = numsSize + 1;
        }
    }

    for (int i = 0; i < numsSize; i++) {
        if (abs(nums[i]) <= numsSize) {
            if (nums[abs(nums[i]) - 1] > 0)
                nums[abs(nums[i]) - 1] *= -1;
        }
    }

    for (int i = 0; i < numsSize; i++) {
        if(nums[i] > 0) {
            return i + 1;
        } 
    }

    return numsSize + 1;
}
154. 寻找旋转排序数组中的最小值 II
int findMin(int* nums, int numsSize){
    int left = 0;
    int right = numsSize - 1;

    while (right - left > 1) {
        int mid = (left + right) / 2;
        if (nums[left] > nums[right]) {
            left = nums[mid] >= nums[left] ? mid : left;
            right = nums[mid] <= nums[right] ? mid : right;
        } else if (nums[left] == nums[right]) {
            right--; ///< only deselect one
        } else {
            return nums[left];
        }
    }

    return nums[left] < nums[right] ? nums[left] : nums[right];
}

排序

451. 根据字符出现频率排序
int getIdx(char x) {
    if (x - 'A' >= 0){
        return x - 'A' > 26 ? x - 'a' + 26 : x - 'A';
    } else {
        return x - '0' + 52;
    }
  
}
char idx2char(int idx) {
    return idx < 26 ? (char)(idx + 'A') : 
        idx < 52 ? (char)(idx - 26 + 'a') : (char)(idx - 52 + '0');
}
int cmp(const void *a, const void *b)
{
    if (((int *)b)[1] != ((int *)a)[1]) {
        return ((int *)b)[1] - ((int *)a)[1];
    } else {
        return ((int *)a)[0] - ((int *)a)[0];
    }
}

char * frequencySort(char * s){
    int len = strlen(s);
    char *res = (char *)malloc(sizeof(char) * (len + 1));
    int hash[62] = {0};
  
    while (len--) {
        hash[getIdx(s[len])]++;
    }

    int tmp[62][2] = {0};
    for (int i = 0; i < 62; i++) {
        int t = hash[i];
        tmp[i][0] = i;
        tmp[i][1] = t;
        //printf("%d ", t);
    }

    qsort(tmp, 62, sizeof(tmp[0]), cmp);

    len = 0;
    for (int i = 0; i < 62; i++) {
        int t = tmp[i][1];
        if (t == 0) {
            break;
        }
      
        while (t--) {
            res[len++] = idx2char(tmp[i][0]);
        }
    }

    res[len] = '\0';

    return res;
}
912. 排序数组
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */

int cp(int *a, int *b) {
    return *a - *b;
}
int* sortArray(int* nums, int numsSize, int* returnSize){
    int *res = (int*) malloc (sizeof(int) * numsSize);
    *returnSize = numsSize;
    memcpy(res,nums,sizeof(int)*numsSize);
    qsort(res,numsSize,sizeof(int),cp);
    return res;
}

贪心

121. 买卖股票的最佳时机
int maxProfit(int* prices, int pricesSize){
    int minPrice = 1e9;
    int maxPro = 0;

    for (int i = 0; i < pricesSize; i++){
        maxPro = maxPro > (prices[i] - minPrice) ? maxPro : (prices[i] - minPrice);
        minPrice = prices[i] < minPrice ? prices[i] : minPrice;
    }
  
    return maxPro;
}

还差得远呢!

关于之前刷题没有及时复习导致重新再看没有什么思路,以及群里一些同学发的稍微复杂一点的问题根本毫无思路的事。。。慢慢重刷ing

之前的题

659. 分割数组为连续子序列
322. 零钱兑换
204. 计数质数
169. 多数元素
98. 验证二叉搜索树
2. 两数相加
3. 无重复字符的最长子串
7. 整数反转
11. 盛最多水的容器

二分法

区间位移-蓝桥杯

数轴上有n个闭区间D1,…,Dn。其中区间Di用一对整数[ai, bi]来描述,满足ai < bi。
已知这些区间的长度之和至少有10000。所以,通过适当的移动这些区间,你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 10000]这个区间内的每一个点都落于至少一个区间内。
  你希望找一个移动方法,使得位移差最大的那个区间的位移量最小。
  具体来说,假设你将Di移动到[ai+ci, bi+ci]这个位置。你希望使得max |ci|  最小。

题解

枚举

n选m个的全排列

从n个当中选m个,有多少种排列呢? 请全输出

输入格式
输入n,m(1≤m≤n≤5)

输出格式
所有可能的排列,字典序

输入输出样例
输入

3 2 1

输出

12 13 21 23 31 32

题解

数据的有效数字

eor&(~eor+1)到lowbit到树状数组

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值