个人学习编程(3-21) leetcode刷题

链接列表的中间值:

  1. 测试用例1: 创建链表 [1, 2, 3, 4, 5],调用 middleNode,预期返回值是 3。
  2. 测试用例2: 创建链表 [1, 2, 3, 4, 5, 6],调用 middleNode,预期返回值是 3。

判断长度,然后length/2

struct ListNode* middleNode(struct ListNode* head){
    int length = 0;
    for(struct ListNode* curr = head;curr != NULL;curr = curr ->next){
        length++;
    }
    //开始计数走length/2步
    struct ListNode* result = head;
    for (int i = 0; i < length/2; i++){
        result = result->next;
    }
    return result;
    
}

使用快慢指针:

struct ListNode* fast = head->next->next;

struct ListNode* low = head->next;

当使用快慢指针的时候,当fast->next==NULL;说明fast已经走到末尾了,但是low刚刚好是fast的一半,因此就可以返回low指针所指的值

但是这里面有一个坑。  不仅要知道 fast != NULL 在 fast的执行途中由于fast是一次跳两个 即 fast->next->next,因此需要保证 fast->next != NULL

代码如下:

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* fast = head;
    struct ListNode* slow = head;

    while (fast != NULL && fast ->next != NULL){
        fast = fast->next->next;
        slow = slow->next;
    }
    return slow;
}

Backspace String Compare:

给定两个字符串 ST,你需要模拟按键操作,即在每个字符串中,# 表示删除前一个字符。返回两个字符串是否相等。

  1. 你需要实现一个函数 backspaceCompare(S, T),该函数返回 True 或 False,表示处理后的两个字符串是否相等。
  2. 示例1:

    Copy Code

    输入:S = "ab#c", T = "ad#c" 输出:true 解释:S 和 T 都会变成 "ac"

    示例2:

    Copy Code

    输入:S = "ab##", T = "c#d#" 输出:true 解释:S 和 T 都会变成 ""

申请一个数组:

新申请一个数组,然后遍历,如果原数组元素不为#则就复制到新数组,如果原数组为#,就先j--,再把  '\0'复制到该下标的上一位元素作为删除操作

void process(char* result_S,const char* S){

    int len_S = strlen(S);
    int j = 0;
    for(int i = 0;i < len_S;i++){
        if (S[i] != '#'){
            result_S[j] = S[i];
            j++;
        } else{
            if(j > 0){
                j--;
            }
        }
    }
    result_S[j] = '\0';
}
bool backspaceCompare(char* S,char* T){
    int len_S = strlen(S);
    char result_S[len_S + 1];
    process(result_S, S);

    int len_T = strlen(T);
    char result_T[len_T + 1];
    process(result_T, T);

    return strcmp(result_S,result_T) == 0;
}

 直接修改原数组

char* process(char* str){
    int len_str = strlen(str);
    int j = 0;
    for (int i = 0;i < len_str;i++){
        if(str[i] != '#'){
            str[j] = str[i];
            j++;
        }
        else{
            if (j > 0){
                j--;
            }
        }
    }
    str[j] = '\0';
    return str;
}
bool backspaceCompare(char* S,char* T){
    return strcmp(process(S),process(T)) == 0;
}

简单的Stack结构体创建:

创建结构体后完成一些操作。

注意:

malloc和realloc后

报错:

obj->data = realloc(obj->data,sizeof(int) * (obj->size + 1));

不报错:

obj->data = (int *)realloc(obj->data,sizeof(int) * (obj->size + 1));

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <bits/stdc++.h>
#include <stack>

typedef struct{
    int* data;
    int size;
} MinStack;

MinStack* minStackCreate() {
    MinStack* s = (MinStack*)malloc(sizeof(MinStack));
    s->data = NULL;
    s->size = 0;
    return s;
}

void minStackPush(MinStack* obj,int x){
    obj->data = (int *)realloc(obj->data,sizeof(int) * (obj->size + 1));
    obj->data[obj->size] = x;
    obj->size++;
}

void minStackPop(MinStack* obj){
    obj->size--;
}

int minStackTop(MinStack* obj){
    return obj->data[obj->size-1];
}

int minStackGetMin(MinStack* obj){
    int min = obj->data[0];
    for (int i = 0; i < obj->size; i++){
        if (obj->data[i] < min)
        {
            min = obj->data[i];
        }
    }
    return min;
}

void minStackFree(MinStack* obj){
    free(obj->data);
    free(obj);
}
int main() {
    MinStack* stack = minStackCreate();

    // 测试 push 操作
    
    minStackPush(stack, 10);
    minStackPush(stack, 20);
    minStackPush(stack, 5);
    minStackPush(stack, 30);
    // 测试 top 操作
    printf("Top of stack: %d\n", minStackTop(stack));  // 30
}

二叉树的直径:

给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。

注意:两结点之间的路径长度是以它们之间边的数目表示。

题意是给一个二叉树,找二叉树里面的最大直径。最大直径的定义是任意两个 node 之间的最大距离。注意这个最大距离很有可能不经过根节点,如下图例子,最大直径是从 9 到 8,摘自LC中文网

struct TreeNode{

        int val;

        struct TreeNode *left;

        struct TreeNode *right;

递归的思想:

/*
// 没有 typedef
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
};

struct TreeNode *root;  // 使用时要写 struct TreeNode

// 使用 typedef
typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;

TreeNode *root;  // 使用时只需要写 TreeNode

*/
#include <stdio.h>
#include <bits/stdc++.h>

typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;

int maxDepth(struct TreeNode* root){
    if (root == NULL) return 0;

    int leftMax = maxDepth(root->left);
    int rightMax = maxDepth(root->right);
    if (leftMax > rightMax){
        return leftMax + 1;
    }
    return rightMax + 1;
}

int diameterOfBinaryTree(struct TreeNode* root){
    if (root == NULL) return 0;
    //一、最长的路径会通过root
    int middle = maxDepth(root->left) + maxDepth(root->right);
    //二、最长的路径不会通过root

    //全在左边
    int left = diameterOfBinaryTree(root->left);
    //全在右边
    int right = diameterOfBinaryTree(root->right);

    int max = middle;
    if (left > max)
    {
        max = left;
    }
    if (right > max)
    {
        max = right;
    }
    return max;
}

最后石头的重量:

有一个石头集合,每个石头都有一个正整数重量值。每次,我们选择两块最重的岩石并将它们粉碎在一起。假设石头的重量为x和y,x <= y。粉碎的结果是:

  • 如果x == y,两块石头都被完全粉碎;

  • 如果x != y,重量为x的石头被完全粉碎,重量为y的石头具有新的重量y-x。

最后,剩下最多1块石头。返回这块石头的重量(如果没有留下石头,则返回0)。

例如:

输入:[2,7,4,1,8,1]
输出:1
说明:
我们将7和8结合起来得到1,所以数组转换为[2,4,1,1,1],
然后我们将2和4结合起来得到2,所以数组转换为[2,1,1,1],
然后我们将2和1结合起来得到1,所以数组转换为[1,1,1],
然后我们将1和1组合起来得到0,所以数组转换为[1],那就是最后一块石头的重量值。

注意

  • 1 <= stones.length <= 30

  • 1 <= stones[i] <= 1000

遍历:

最后数组的值就  y = 0 x = 0 返回0 

y>0  x = 0 返回y

y!=0 && x!=0 继续比较

int extractMax(int* stones,int stonesSize){
    int max = stones[0];
    for (int i = 0; i < stonesSize; i++){
        if (stones[i > max]){
            max = stones[i];
        }
    }
    for (int i = 0; i < stonesSize; i++){
        if (stones[i] == max){
            stones[i] = 0;
            break;
        }
    }
    return max;
}
void insert(int* stones,int stonesSize,int value){
    for (int i = 0; i < stonesSize; i++){
        if (stones[i] == 0){
            stones[i] = value;
            return;
        }
    }
}

int lastStoneWeight(int* stones,int stonesSize){
    while (true){
        int y = extractMax(stones,stonesSize);
        int x = extractMax(stones,stonesSize);
        if (x == 0){
            return y;
        }
        if (x != y){
            insert(stones,stonesSize,y - x);
        }    
    }
    return 0;
}

奇数在前,偶数在后:

int v[10] = {1, 4, 5, 2, 3, 8, 6, 9, 7, 10};

  1. 所有奇数将排在前面。
  2. 奇数内部按原始顺序排布。
  3. 所有偶数将排在后面。
  4. 偶数内部按原始顺序排布。

所以输出的数组将是:1 5 3 9 7 4 2 8 6 10

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

int cmp(const void* a,const void* b){
    int va = *(const int*)a;
    int vb = *(const int*)b;
    //va,vb同为奇数的话,return 0 不需要改变
    if (va % 2 == 1 && vb % 2 == 1){
        return 0; //不改变
    }
    //va为奇数,vb为偶数,return -1 让va排在vb前面
    if (va % 2 == 1 && vb % 2 ==0){
        return -1;
    }
    //va为偶数,vb为奇数,return -1 让vb排在va前面
    if (va % 2 == 0 && vb % 2 ==1){
        return 1;
    }
    //如果 va 是偶数,vb 是奇数,返回 1,让 vb 排在 va 前面
    if (va % 2 == 0 && vb % 2 == 0) {
        return 0;
    }
    //如果 va 和 vb 都是偶数,返回 0,不改变顺序
    return 0;
}



int main() {
    int v[10] = {1,4,5,2,3,8,6,9,7,10};
    qsort(v, 10, sizeof(int), cmp);
    for (int i = 0; i < 10; i++){
        printf("%d ",v[i]);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值