力扣部分题解

一.leetcode部分报错的含义

1.Char 5: fatal error: control may reach end of non-void function [-Wreturn-type] }

这表示:没有考虑所有可能的返回值情况

2.AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318

这类报错表示:检查了是否存在内存非法访问,例如数组越界

3.AddressSanitizer:DEADLYSIGNAL

这表示数组越界

4.member access within null pointer of type 'TreeNode'

这类报错表示:未考虑参数空值异常

5.terminate called after throwing an instance of 'std::out_of_range' what(): basic_string::substr

这类问题的解决方法:查找substr方法前后代码,排除可能的越界条件。
二.leetcode部分题目题解
T20.有用的括号
在这里插入图片描述

在这里插入图片描述
思路:由栈先入后出的特点与本题特点大致相似,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack 仍然为空;

遇到左括号入栈,遇到右括号和栈顶元素比较,若不匹配或栈空,直接返回false。

最后若栈非空,返回false,否则返回true

bool isValid(char * s){
    if(!s||s[0]=='\0')
        return true;
    char *stack=(char *)malloc(strlen(s));
    memset(stack,0,strlen(s));//初始化内存空间
    int top=-1;//初始化顺序栈 
    int i;
    for(i=0;s[i]!='\0';i++){
        switch(s[i]){
            case'(':
                stack[++top]=s[i];//进栈 
                break;
            case'{':
                stack[++top]=s[i];//进栈 
                break;
            case'[':
                stack[++top]=s[i];//进栈 
                break;
            case')':
                if(top<0||stack[top--]!='(')//判断是否栈为空或与之匹配的字符不对应 
                    return false;
                 break;
            case'}':
                if(top<0||stack[top--]!='{')//同上 
                    return false;
                break;  
            case']':
                if(top<0||stack[top--]!='[')//同上 
                    return false;
                break;     
        }
    }
    if(top>=0)
            return false;//说明栈中的元素未全部匹配 
    return true;
}} 

2.T86.分隔链表
在这里插入图片描述
思路:对所有小于 x 的节点使用头插法并移动头结点到该节点处;等于 x 的节点头插完后不移动头结点

struct ListNode* partition(struct ListNode* head, int x){
    if(head == NULL){
        return head;
    }
    struct ListNode* HNode;
    HNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    HNode->next = head;//创建头结点HNode指向该结点head,
    struct ListNode* insertPos = HNode;
    for(;insertPos->next && insertPos->next->val < x;insertPos = insertPos->next);//遍历到小与x的节点处
    if(insertPos->next == NULL){
        return head;
    }
    struct ListNode* left_pre = insertPos->next;
    struct ListNode* right_cur = left_pre;
    struct ListNode* split = left_pre;
    while(left_pre->next != NULL){
        if(left_pre->next->val >= x){
            left_pre = left_pre->next;
            right_cur = left_pre;
        }
        else if(right_cur->next && right_cur->next->val < x){
            right_cur = right_cur->next;
        }
        else{
            split = insertPos->next;
            insertPos->next = left_pre->next;
            left_pre->next = right_cur->next;
            right_cur->next = split;
            insertPos = right_cur;
        }
    }
    head = HNode->next;
    free(HNode);
    return head;
}} 

3.T100.相同的树
在这里插入图片描述
在这里插入图片描述

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {
    if(p == NULL && q == NULL) return true;
    if(p != NULL && q != NULL){
        if(p -> val != q -> val) return false;//判断数值是否相同
        else{
            return (isSameTree(p -> left, q -> left) && isSameTree(p -> right, q -> right));//使用递归的方法判断两个二叉树是否相同 
        }
    }
    else
        return false;
}

4.T102.二叉树的层序遍历
在这里插入图片描述
在这里插入图片描述
思路:二叉树的层序遍历即按照从根节点开始逐层输出

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    int **rslt = NULL;
    int *columnSize = NULL;
    struct TreeNode *queue[NODE_SIZE] = {0};       /* 做队列使用 */          
    struct TreeNode *pNode = NULL;
    int front = 0, rear = 0, pre_rear;
    int i = 0, j = 0;                                           /* i用来索引行,即层数,j用来索引列,即每层的结点个数 */

    if (!root) {
        *returnSize = 0;
        return NULL;
    }
    queue[rear++] = root;                                                  /* 先把root结点入队 */
    while (front < rear) {                                      /* 外层循环:用来处理队列,队列不为空就循环处理 */
        pre_rear = rear;                                        /* 备份上一层的队尾指针 */
        rslt = realloc(rslt, (i + 1)*sizeof(int *));            /* 外层循环实际就是层数,每次扩充1 */
        rslt[i] = calloc(pre_rear - front, sizeof(int));
        while(front < pre_rear) {                               /* 内层循环:遍历每一层结点,每次出队一个结点,同时并把该结点的孩子入队 */
            pNode = queue[front++];                             /* 出队 */
            rslt[i][j++] = pNode->val;                          /* 存储结点值 */
            if (pNode->left)                                    /* 当前结点左、右孩子存在则将他们入队 */
                queue[rear++] = pNode->left;
            if (pNode->right)
                queue[rear++] = pNode->right;
        }
        columnSize = realloc(columnSize, (i + 1)*sizeof(int));  /* columnSize数组用来存储每层结点个数 */
        columnSize[i++] = j;
        j = 0;
    }

    *returnSize = i;                                            //这个参数用来“带回”层数 */
    *returnColumnSizes = columnSize;                            /* 这个参数用来“带回”每层的结点个数 */

    return rslt;                                                /* 返回值存储了遍历的结果,上面两个参数用来描述这个结果,以便调用者打印树的形态 */
}

5.T225.用队列实现栈
在这里插入图片描述
在这里插入图片描述
一下是思路导图
在这里插入图片描述
思路解析:入栈操作时,首先获得入栈前的元素个数 n,然后将元素入队到队列,再将队列中的前 n 个元素(即除了新入栈的元素之外的全部元素)依次出队并入队到队列,此时队列的前端的元素即为新入栈的元素,且队列的前端和后端分别对应栈顶和栈底。

由于每次入栈操作都确保队列的前端元素为栈顶元素,因此出栈操作和获得栈顶元素操作都可以简单实现。出栈操作只需要移除队列的前端元素并返回即可,获得栈顶元素操作只需要获得队列的前端元素并返回即可(不移除元素)。

由于队列用于存储栈内的元素,判断栈是否为空时,只需要判断队列是否为空即可

typedef struct tagListNode {
    struct tagListNode* next;
    int val;
} ListNode;

typedef struct {
    ListNode* top;
} MyStack;

MyStack* myStackCreate() {
    MyStack* stk = calloc(1, sizeof(MyStack));
    return stk;
}

void myStackPush(MyStack* obj, int x) {
    ListNode* node = malloc(sizeof(ListNode));
    node->val = x;
    node->next = obj->top;
    obj->top = node;
}

int myStackPop(MyStack* obj) {
    ListNode* node = obj->top;
    int val = node->val;
    obj->top = node->next;
    free(node);

    return val;
}

int myStackTop(MyStack* obj) {
    return obj->top->val;
}

bool myStackEmpty(MyStack* obj) {
    return (obj->top == NULL);
}

void myStackFree(MyStack* obj) {
    while (obj->top != NULL) {
        ListNode* node = obj->top;
        obj->top = obj->top->next;
        free(node);
    }
    free(obj);
}

6.T455.分发饼干
在这里插入图片描述

int cmp(int*a,int *b)
 {
  return *a-*b;
 }
int findContentChildren(int* g, int gSize, int* s, int sSize){
    int i=0,j=0;
    qsort(g,gSize,sizeof(int),cmp);//从小到大排序
    qsort(s,sSize,sizeof(int),cmp);
    while(i<gSize&&j<sSize){
        if(g[i]<=s[j])  i++;
        j++;
    }
    return i;
}

7.T459.重复的子字符串
在这里插入图片描述
首先给大家介绍一下kmp(字符串匹配算法),大家点下面这个链接,可看到详细的讲解
kmp
这是题目解答

#define MAX_NUM 10001
bool repeatedSubstringPattern(char * s){
    int len = strlen(s);
    if (len <= 1) {
        return false;
    }
    int i;
    int match = 0;
    for (i = 1; i * 2 <= len; i++) {
        if (len % i == 0) {
            int j;
            for (j = i; j < len; j++) {
                if (s[j] == s[j - i]) {
                    match = 1;
                } else {
                    match = 0;
                    break;
                }
            }
            if (match == 1) {
                return true;
            }
        }
    }
    return false;
}

8.T463.岛屿的周长
在这里插入图片描述

class Solution {
public:

    int islandPerimeter(vector<vector<int>>& grid) {
        int cnt = 0;
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[i].size(); j++){
                //如果当前值为1,加4(四条边)
                if(grid[i][j] == 1){
                    cnt += 4;
                }
                //如果左边有1,减2(两条边重合),上面有1,减2。
                if(j-1>=0 && grid[i][j] == 1 && grid[i][j-1] == 1){
                    cnt -= 2;
                }
                if(i-1>=0 && grid[i][j] == 1 && grid[i-1][j] == 1){
                    cnt -= 2;
                }
            }
        }
        return cnt;
    }
};

今天的题解就写到这了。。。哒哒哒,拜拜

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值