【无标题】

2022.04.19 21:40 - 22:40

(设计题)LRU 缓存

https://leetcode-cn.com/problems/lru-cache/

  1. HASH_ITER的使用,从最后开始遍历数组
HASH_ITER(hh, g_usr, cur_usr, next_usr)
  1. UT_HASH本身就是一个优秀的双链表实现,可用于快速查找,快速插入

  2. HASH_COUNT的使用, 用于统计当前HASH中有多少数据

  3. 代码实现

typedef struct {
    int key;
    int value;
    UT_hash_handle hh;
} LRUCache;

LRUCache *g_usr = NULL;
int g_size;

LRUCache* lRUCacheCreate(int capacity) {
    g_size = capacity;
    return g_usr;
}

int lRUCacheGet(LRUCache* obj, int key) {
    LRUCache *cur_usr = NULL;
    HASH_FIND_INT(g_usr, &key, cur_usr);
    if(cur_usr != NULL) {
        HASH_DEL(g_usr, cur_usr);
        HASH_ADD_INT(g_usr, key, cur_usr);
        return cur_usr->value;
    }
    return -1;
}

void lRUCachePut(LRUCache* obj, int key, int value) {
    LRUCache *cur_usr = NULL;
    LRUCache *next_usr = NULL;

    HASH_FIND_INT(g_usr, &key, cur_usr);
    if(cur_usr != NULL) {
        HASH_DEL(g_usr, cur_usr);
        cur_usr->value = value;
        cur_usr->key = key;
        HASH_ADD_INT(g_usr, key, cur_usr);
    } else {
        int cnt = HASH_COUNT(g_usr);
        if(cnt == g_size) {
            HASH_ITER(hh, g_usr, cur_usr, next_usr) {
                HASH_DEL(g_usr, cur_usr);
                free(cur_usr);
                break;
            }
        }
        LRUCache *new_usr = (LRUCache*)malloc(sizeof(LRUCache));
        new_usr->key = key;
        new_usr->value = value;
        HASH_ADD_INT(g_usr, key, new_usr);
    }
    return;
}

void lRUCacheFree(LRUCache* obj) {
    LRUCache *cur_usr = NULL;
    LRUCache *next_usr = NULL;
    HASH_ITER(hh, g_usr, cur_usr, next_usr) {
        HASH_DEL(g_usr, cur_usr);
        free(cur_usr);
    }
}

2022.04.19 22:40 - 23:03

(基础题)链表排序

https://leetcode-cn.com/problems/insertion-sort-list/submissions/

https://leetcode-cn.com/problems/sort-list/

  1. 插入排序的思想:
    插入排序的基本思想是,维护一个有序序列,初始时有序序列只有一个元素,每次将一个新的元素插入到有序序列中,将有序序列的长度增加 11,直到全部元素都加入到有序序列中。
  2. 入参判断
  3. 链表的插入和恢复
            struct ListNode* prev = dummyHead;
            while(prev->next->val <= curr->val) {
                prev = prev->next;
            }
            lastSorted->next = curr->next;
            curr->next = prev->next;
            prev->next = curr;
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* insertionSortList(struct ListNode* head)
{
    if(head == NULL) {
        return head;
    }
    struct ListNode* dummyHead = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummyHead->val = 0;
    dummyHead->next = head;
    struct ListNode* lastSorted = head;
    struct ListNode* curr = head->next;
    while(curr != NULL) {
        if(lastSorted->val <= curr->val) {
            lastSorted = lastSorted -> next;
        } else {
            struct ListNode* prev = dummyHead;
            while(prev->next->val <= curr->val) {
                prev = prev->next;
            }
            lastSorted->next = curr->next;
            curr->next = prev->next;
            prev->next = curr;
        }
        curr = lastSorted->next;
    }
    return dummyHead->next;
}

2022.04.24 22:40~23:29

(基础题) 堆排序 最大平均通过率

https://leetcode-cn.com/problems/maximum-average-pass-ratio/

  1. 大根堆概念
  2. 大根堆创建
  3. 大根堆维护 (增长率作为排序的输入条件)
  4. 大根堆模板要记住
double calc(int* a)
{
    return (double)(a[0] + 1) / (a[1] + 1) - (double)a[0] / a[1];
}

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

void maxHeapify(int **classes, int n, int i)
{
    int largest = i;
    int l = 2 * i + 1;
    int r = 2 * i + 2;
    if(l < n && calc(classes[l]) > calc(classes[largest])) {
        largest = l;
    }
    if(r < n && calc(classes[r]) > calc(classes[largest])) {
        largest = r;
    }
    if( i != largest) {
        swap(&classes[i], &classes[largest]);
        maxHeapify(classes, n, largest);
    }
}




double maxAverageRatio(int** classes, int classesSize, int* classesColSize, int extraStudents)
{
    int i;
    int n = classesSize;
    double aveSum = 0.0;
    for(i = n / 2 - 1; i >= 0; i--) {
        maxHeapify(classes, n, i);
    }
    classes[0][0]++;
    classes[0][1]++;
    for( i = 1; i < extraStudents; i++) {
        maxHeapify(classes, classesSize, 0);
        classes[0][0]++;
        classes[0][1]++;
    }
    for(i = 0; i < classesSize; i++) {
        aveSum += (double)classes[i][0] / (double)classes[i][1];
    }
    return aveSum / classesSize;
}

#2022.04.30 23:00-23:50

(单调栈)小行星碰撞

https://leetcode-cn.com/problems/XagZNi/

  1. 单调栈特殊处理
  2. 正负号判断
bool IsNeedCash(int a, int b)
{
    if(((a & ACTIVE) == 0) && ((b & ACTIVE) == ACTIVE)) {
        return true;
    }
    return false;
}
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
#define ACTIVE 0x8000

bool IsNeedCash(int a, int b)
{
    if(((a & ACTIVE) == 0) && ((b & ACTIVE) == ACTIVE)) {
        return true;
    }
    return false;
}
int* asteroidCollision(int* asteroids, int asteroidsSize, int* returnSize)
{
    int* stack = (int*)malloc(sizeof(int) * asteroidsSize);
    memset(stack, 0, sizeof(int) * asteroidsSize);
    int top = -1;
    for(int i = 0; i < asteroidsSize; i++) {
        top += 1;
        stack[top] = i;
        while(top > 0 && IsNeedCash(asteroids[stack[top - 1]], asteroids[stack[top]])) {
            if(abs(asteroids[stack[top - 1]]) == abs(asteroids[stack[top]])) {
                top -= 2;
            } else {
                int tmp = abs(asteroids[stack[top - 1]]) > abs(asteroids[stack[top]]) ?  stack[top - 1] : stack[top];
                top -= 1;
                stack[top] = tmp; 
            }
        }

    }
    int* res = (int*)malloc(sizeof(int) * (top + 1));
    for(int i = 0; i <= top; i++) {
        res[i] = asteroids[stack[i]];
    }
    *returnSize = top + 1;
    free(stack);
    return res;
}

动态规划 有点像DFS

通过这两个好好研究下DFS

  1. 礼物的最大价值
    https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/

int Max(int a, int b)
{
    return a > b ? a : b;
}


#define MAXLEN 201

int dp[MAXLEN][MAXLEN];

int maxValue(int** grid, int gridSize, int* gridColSize)
{
  int  m = gridSize;
  int  n = gridColSize[0];
  memset(dp, 0, sizeof(int) * MAXLEN * MAXLEN);

  dp[0][0] = grid[0][0];

  for(int i = 1; i < m; i++) {
      dp[i][0] = dp[i - 1][0] + grid[i][0];
  }

  for(int j = 1; j < n; j++) {
      dp[0][j] = dp[0][j - 1] + grid[0][j];
  }

  for(int i = 1; i <m; i++) {
      for(int j = 1; j < n; j++) {
          dp[i][j] =  Max(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
      }
  }
    return dp[m - 1][n - 1];
}
  1. 第K条最小指令
    https://leetcode-cn.com/problems/kth-smallest-instructions/
char * kthSmallestPath(int* destination, int destinationSize, int k)
{
    int m = destination[0];
    int n = destination[1];

    int help[m + 1][n + 1];

    for(int i = 0; i <=m; i++) {
        help[i][0] = 1;
    }

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

    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= n; j++) {
            help[i][j] = help[i][j - 1] + help[i - 1][j];
        }
    }

    char* res = (char*)malloc(sizeof(char) * (m + n + 1));

    int col = m;
    int row = n;

    for(int i = 0; i < m + n; i++) {
        if(row > 0 && k <= help[col][row - 1]) {
            res[i] = 'H';
            row--;
        } else {
            if(row > 0) {
                k -= help[col][row - 1];
            } 
            res[i] = 'V';
            col--;
        }
    }
    res[m + n] = '\0';
    return res;
}

双指针特殊题型

https://leetcode-cn.com/problems/find-the-winner-of-an-array-game/
找出数组游戏的赢家

int getWinner(int* arr, int arrSize, int k)
{
    int max = arr[0] > arr[1] ? arr[0] : arr[1];
    int count = 1;
    for(int i = 2; i < arrSize; i++) {
        if(count >= k) {
            break;
        }
        if(arr[i] <= max) {
            count += 1;
        } else{
            max = arr[i];
            count = 1; 
        }
    }
    return max;
}

BFS

单词拆分
https://leetcode-cn.com/problems/word-break/

  1. 保存可以延申的下标作为入队条件
bool CmpString(char* s1, char* s2, int len)
{
    for(int i = 0; i < len; i++) {
        if(s1[i] != s2[i]) {
            return false;
        }
    }
    return true;
}

bool wordBreak(char * s, char ** wordDict, int wordDictSize)
{
    int lens = strlen(s);

    int* visited = (int*)malloc(sizeof(int) * (lens + 1));
    memset(visited, 0, sizeof(int) * (lens + 1));

    int* queryArr = (int*)malloc(sizeof(int) * (lens + 1));
    memset(queryArr, 0, sizeof(int) * (lens + 1));

    int head = 0;
    int tail = 0;
    visited[0] = 1;
    queryArr[tail] = 0;
    tail += 1;
    while(head < tail) {
        int tmp_index = queryArr[head];
        for(int i = 0; i < wordDictSize; i++) {
            int tmpLens = strlen(wordDict[i]);
            if(tmpLens + tmp_index > lens) {
                continue;
            }
            if(visited[tmp_index + tmpLens] == 1) {
                continue;
            }
            if(CmpString(&s[tmp_index], wordDict[i], tmpLens) == true) {
                if(tmpLens + tmp_index == lens) {
                    return true;
                }
                queryArr[tail] = tmp_index + tmpLens;
                tail += 1;
                visited[tmp_index + tmpLens] = 1;
            }
        }
        head += 1;
    }
    return false;
}

贪心

翻转矩阵后的得分
https://leetcode-cn.com/problems/score-after-flipping-matrix/
1.先将行的第一个全部反转为1
2.再反转列, 数值增大反转 否则不反转
3.不必真的反转,只统计贡献值就可以

int matrixScore(int** grid, int gridSize, int* gridColSize)
{
    int row = gridSize;
    int col = gridColSize[0];

    int ret = row * (1 << (col - 1));

    for(int i = 1; i < col; i++) {
        int nOnes = 0;
        for(int j = 0; j < row; j++) {
            if(grid[j][0] == 1) {
                nOnes += grid[j][i];
            } else {
                nOnes += (1 - grid[j][i]);
            }
        }
    int k = nOnes > row - nOnes ? nOnes : row - nOnes;
    ret += k * (1 << (col - i - 1));
    }
    return ret;
}

回溯

2.全部子集

int** ans;
int* ansColSize;
int ansSize;

int* t;
int tSize;


void dfs(int cur, int* nums, int numsSize)
{
    if(cur == numsSize) {
        // 存结果
        int* tmp = (int*)malloc(sizeof(int) * numsSize);
        memcpy(tmp, t, sizeof(int) * numsSize);
        ans[ansSize] = tmp;
        ansColSize[ansSize] = tSize;
        ansSize +=1;
        return;
    }
    t[tSize++] = nums[cur];
    dfs(cur + 1, nums, numsSize);
    tSize -= 1;
    dfs(cur + 1, nums, numsSize);
}


int** subsets(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) 
{
    ans = (int**)malloc(sizeof(int*) * (1 << numsSize));
    ansColSize = (int*)malloc(sizeof(int) * (1 << numsSize));

    t = (int*)malloc(sizeof(int) * numsSize);
    ansSize = 0;
    tSize = 0;
    dfs(0, nums, numsSize);
    * returnSize = 1 << numsSize;
    *returnColumnSizes = ansColSize;
    return ans;
}

1.全排列

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

int** ans;
int* ansCol;
int ansSize;

int* path;


int g_used[1000] = {0};


void dfs(int cur, int* nums, int numsSize)
{
    if(cur == numsSize) {
        int* tmpx = (int*)malloc(sizeof(int) * numsSize);
        memcpy(tmpx, path, sizeof(int) * numsSize);
        ans[ansSize] = tmpx;
        ansCol[ansSize] = numsSize;
        ansSize += 1;
        return;
    }
    for(int i = 0; i < numsSize; i++) {
        if(g_used[i] == 1) {
            continue;
        }
        path[cur] = nums[i];
        g_used[i] = 1;
        dfs(cur + 1, nums, numsSize);
        g_used[i] = 0;
    }
}



int** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes)
{
    memset(g_used, 0, sizeof(g_used));
    ans = (int**)malloc(sizeof(int*) * (100000));
    ansCol = (int*)malloc(sizeof(int)* (100000));
    path = (int*)malloc(sizeof(int)* (numsSize));
    ansSize = 0;
    dfs(0, nums, numsSize);
    *returnSize = ansSize;
    *returnColumnSizes = ansCol;
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值