10.18--一下午连肝20道leetcode题(纯C实现)

文章目录

    • 题目
      • 20.有效的括号
      • 155.最小栈
      • 225.用队列实现栈
      • 232.用栈实现队列
      • 234.回文链表
      • 844.比较含退格的字符
      • 682.棒球比赛
      • 1047. 删除字符串中的所有相邻重复项
      • 1441.用栈构建数组
      • 1475.商品折扣后的最终价格
      • 1544.整理字符串
      • 1598. 文件夹操作日志搜集器
      • 1614. 括号的最大嵌套深度
      • 150. 逆波兰表达式求值
      • 735. 行星碰撞
      • 1.两数之和
      • 167. 两数之和 II - 输入有序数组
      • 806. 写字符串需要的行数
      • 821. 字符的最短距离
      • 832. 翻转图像
    • 解题代码与分析
      • 20.有效的括号
      • 155.最小栈
      • 225.用队列实现栈
      • 232.用栈实现队列
      • 234.回文链表
      • 844.比较含退格的字符
      • 682.棒球比赛
      • 1047. 删除字符串中的所有相邻重复项
      • 1441. 用栈操作构建数组
      • 1475.商品折扣后的最终价格
      • 1544.整理字符串
      • 1598. 文件夹操作日志搜集器
      • 1614. 括号的最大嵌套深度
      • 150. 逆波兰表达式求值
      • 735. 行星碰撞
      • 1.两数之和
        • 自己手写简单哈希表解题
      • 167. 两数之和 II - 输入有序数组
      • 806. 写字符串需要的行数
      • 821. 字符的最短距离
      • 832.翻转图像

题目

20.有效的括号

10.18--一下午连肝20道leetcode题(纯C实现)_第1张图片

155.最小栈

10.18--一下午连肝20道leetcode题(纯C实现)_第2张图片

225.用队列实现栈

10.18--一下午连肝20道leetcode题(纯C实现)_第3张图片

232.用栈实现队列

10.18--一下午连肝20道leetcode题(纯C实现)_第4张图片

234.回文链表

10.18--一下午连肝20道leetcode题(纯C实现)_第5张图片

844.比较含退格的字符

10.18--一下午连肝20道leetcode题(纯C实现)_第6张图片

682.棒球比赛

10.18--一下午连肝20道leetcode题(纯C实现)_第7张图片

1047. 删除字符串中的所有相邻重复项

10.18--一下午连肝20道leetcode题(纯C实现)_第8张图片

1441.用栈构建数组

10.18--一下午连肝20道leetcode题(纯C实现)_第9张图片

1475.商品折扣后的最终价格

10.18--一下午连肝20道leetcode题(纯C实现)_第10张图片

1544.整理字符串

10.18--一下午连肝20道leetcode题(纯C实现)_第11张图片

1598. 文件夹操作日志搜集器

10.18--一下午连肝20道leetcode题(纯C实现)_第12张图片

1614. 括号的最大嵌套深度

10.18--一下午连肝20道leetcode题(纯C实现)_第13张图片

150. 逆波兰表达式求值

10.18--一下午连肝20道leetcode题(纯C实现)_第14张图片

735. 行星碰撞

10.18--一下午连肝20道leetcode题(纯C实现)_第15张图片

1.两数之和

10.18--一下午连肝20道leetcode题(纯C实现)_第16张图片

167. 两数之和 II - 输入有序数组

10.18--一下午连肝20道leetcode题(纯C实现)_第17张图片

806. 写字符串需要的行数

10.18--一下午连肝20道leetcode题(纯C实现)_第18张图片

821. 字符的最短距离

10.18--一下午连肝20道leetcode题(纯C实现)_第19张图片

832. 翻转图像

10.18--一下午连肝20道leetcode题(纯C实现)_第20张图片

解题代码与分析

20.有效的括号

很简单的栈的运用题,通过左右括号的限制栈的入和出。

bool checkL(char x){
     
    return x=='('||x=='{'||x=='[';
}
bool checkR(char x){
     
    return x==')'||x=='}'||x==']';
}
bool isMatch(char a,char b){
     
    switch(a){
     
        case '(':
            return b==')';
        case '{':
            return b=='}';
        case '[':
            return b==']';
    }
    return false;
}
bool isValid(char * s){
     
    int n = strlen(s);
    int top = 0;//这里top指向stack的长度
    char stack[10005];
    for(int i=0;i<n;i++){
     
        if(checkL(s[i])){
     
            stack[top++] = s[i];
        }else if(checkR(s[i])){
     
            if(top==0)
                return false;
            if(isMatch(stack[top-1],s[i]))
                top--;
            else return false;
        }
    }
    return top==0;
}

155.最小栈

我的做法很朴素,保持最小元素在栈顶即可,只需要对每次入栈操作特殊处理,当栈为空的时候只需要入一个元素,如果栈不为空,则对当前要入的元素进行判断,得出更小的一个元素,然后多入一个元素到栈顶,也就是这个更小的元素,这样也就相当于除了最开始情况下是入一个,其余情况都是两个两个的入栈,所以每次出栈除了最开始的一个情况外都需要 -= 2

#define SIZE 15000
typedef struct {
     
    int nums[SIZE];
    int top;
} MinStack;

/** initialize your data structure here. */

MinStack* minStackCreate() {
     
  MinStack* obj = malloc(sizeof(MinStack));
  obj->top = -1;
  return obj;
}
//重点就在于push和pop的处理
void minStackPush(MinStack* obj, int val) {
     
    //当栈空时只入一个,其他情况将栈顶与入栈元素进行比较,保持最小的元素在栈顶,入栈元素在栈顶的下一个。
    if(obj->top==-1)
    obj->nums[++(obj->top)] = val;
    else{
     
        int min = obj->nums[obj->top]>val?val:obj->nums[obj->top];
        obj->nums[++(obj->top)] = val;
        obj->nums[++(obj->top)] = min; 
    }
}

void minStackPop(MinStack* obj) {
     
    //若到了最后一个元素,则底下没有其他东西垫底需要特殊处理。
    //当栈为空则top不动。
    if(obj->top==-1){
     
        return;
    }
    //确保top指向最小值
    if(obj->top==0){
     
        obj->top=-1;
        return;
    }
    obj->top-=2;
}
//关键就在于能改变top指针的操作的设计,而下面两个不能影响top指针,所以很是简单。。
int minStackTop(MinStack* obj) {
     
    if(obj->top==0){
     
        return obj->nums[obj->top];
    }
    return obj->nums[obj->top-1];
}

int minStackGetMin(MinStack* obj) {
     
    return obj->nums[obj->top];
}

void minStackFree(MinStack* obj) {
     
    free(obj);
}

225.用队列实现栈

用C语言的话,只要对队列的实现较为熟悉应该都好做,我们需要两个队列实现一个栈的话,需要能够熟练的运用好这两个队列,其中一个队列我们作为中转站,也就是,每次如果要执行栈的pop得到栈顶,则我们需要不断的对队列进行pop,然后转移到另一个中转站,直到只剩一个元素,则这个就是栈顶元素,返回这个元素即可。上面这些描述是对栈的pop和top操作中都需要做的操作,以下就是有一些不一样了:
对于pop操作:进行上述操作后,我们需要再把中转站变成要操作的队列(指针交换),注意还需要把这剩下的最后一个元素pop。
对于top操作:进行上述操作后,需要再执行一次push操作,然后再指针交换。

  • 结合代码进行观看体验更佳。
#define MAXLEN 20
typedef struct{
     
    int* date;
    int front;
    int rear;
}queue;
typedef struct {
     
    queue* Q1;
    queue* Q2;
} MyStack;


MyStack* myStackCreate() {
     
    MyStack* res = (MyStack*)malloc(sizeof(MyStack));
    res->Q1 = (queue*) malloc(sizeof(queue));
    res->Q2 = (queue*) malloc(sizeof(queue));
    res->Q1->date = (int*)malloc(sizeof(int)*MAXLEN);
    res->Q2->date = (int*)malloc(sizeof(int)*MAXLEN);
    res->Q1->front = res-> Q1->rear = res->Q2->front = res->Q2->rear = 0;
    return res;
}

void myStackPush(MyStack* obj, int x) {
     
    obj->Q1->date[obj->Q1->rear%MAXLEN] = x;//一个栈负责入
    obj->Q1->rear++;
}

int myStackPop(MyStack* obj) {
     
    while((obj->Q1->front+1)%MAXLEN != (obj->Q1->rear)%MAXLEN){
     //把队列push到另外一个队列,只剩下一个元素为止
        obj->Q2->date[obj->Q2->rear%MAXLEN] = obj->Q1->date[obj->Q1->front%MAXLEN];
        obj->Q2->rear++,obj->Q1->front++;
    }
    //交换指针内容
    queue* t = obj->Q1;
    obj->Q1 = obj->Q2;
    obj->Q2 = t;
    return obj->Q2->date[obj->Q2->front++];
}

int myStackTop(MyStack* obj) {
     
    while((obj->Q1->front+1)%MAXLEN != (obj->Q1->rear)%MAXLEN){
     //把队列push到另外一个队列,只剩下一个元素为止
        obj->Q2->date[obj->Q2->rear%MAXLEN] = obj->Q1->date[obj->Q1->front%MAXLEN];
        obj->Q2->rear++,obj->Q1->front++;
    }
    int res = obj->Q1->date[obj->Q1->front];
    obj->Q2->date[obj->Q2->rear%MAXLEN] = obj->Q1->date[obj->Q1->front%MAXLEN];
    obj->Q2->rear++,obj->Q1->front++;
    //交换指针内容
    queue* t = obj->Q1;
    obj->Q1 = obj->Q2;
    obj->Q2 = t;
    return res;
}

bool myStackEmpty(MyStack* obj) {
     
    return obj->Q1->front == obj->Q1->rear;
}

void myStackFree(MyStack* obj) {
     
    free(obj->Q1->date);
    obj->Q1->date = NULL;
    free(obj->Q2->date);
    obj->Q2->date = NULL;
    free(obj->Q1);
    obj->Q1 = NULL;
    free(obj->Q2);
    obj->Q2 = NULL;
    free(obj);
    obj = NULL;
}

232.用栈实现队列

用栈实现队列,单纯的是利用另外一个栈来实现倒序的功能,使得末端变首端,需要注意的是我们只需要一个队列用于push,另一个队列用于 pop 和 front 即可,完全不需要中转站这种操作,需要注意只有当用于 pop 和 front的栈空了,才需要重新补给!

/* 两个栈实现队列, S1,S2          */
/* 入队操作: push元素进入S1       */
/* 出队操作: S2非空时, 从S2弹出元素, S2为空, S1数据导入S2再弹出 */
#define MAXLEN 20
typedef struct{
     
    int* date;
    int top;
}stack;
typedef struct {
     
    stack* S1;
    stack* S2;
} MyQueue;


MyQueue* myQueueCreate() {
     
    MyQueue* Q = (MyQueue*)malloc(sizeof(MyQueue));
    Q->S1 = (stack*)malloc(sizeof(stack));Q->S2 = (stack*)malloc(sizeof(stack));
    Q->S1->date = (int*)malloc(sizeof(int)*MAXLEN); 
    Q->S2->date = (int*)malloc(sizeof(int)*MAXLEN);
    Q->S1->top = Q->S2->top = 0;
    return Q;
}
/* push元素时, 只往S1中push */
void myQueuePush(MyQueue* obj, int x) {
     
    obj->S1->date[obj->S1->top++] = x;
}
/* pop元素时, S2非空时, 弹出; S2为空, S1数据导入S2中, 继续从S2弹出数据 */
int myQueuePop(MyQueue* obj) {
     
    if((obj->S2->top)>0)
        return obj->S2->date[--(obj->S2->top)];
    while(obj->S1->top > 0){
     
        obj->S2->date[obj->S2->top] = obj->S1->date[--(obj->S1->top)];
        obj->S2->top++;
    }
    return obj->S2->date[--(obj->S2->top)];
}

int myQueuePeek(MyQueue* obj) {
     
    if((obj->S2->top)>0)
        return obj->S2->date[(obj->S2->top)-1];
    while(obj->S1->top > 0){
     
        obj->S2->date[obj->S2->top] = obj->S1->date[--(obj->S1->top)];
        obj->S2->top++;
    }
    return obj->S2->date[obj->S2->top-1];
}

bool myQueueEmpty(MyQueue* obj) {
     
    return obj->S1->top == 0&&obj->S2->top==0;
}

/* 释放申请的空间 */
void myQueueFree(MyQueue* obj) {
         
    free(obj->S1->date);
    obj->S1->date = NULL;
    free(obj->S2->date);
    obj->S2->date = NULL;
    free(obj->S1);
    obj->S1 = NULL;
    free(obj->S2);
    obj->S2 = NULL;
    free(obj);
    obj = NULL;
}

234.回文链表

链表题乱入

typedef struct ListNode ListNode;

ListNode* getHalf(ListNode* head) {
     

    ListNode* fast = head;

    ListNode* slow = head;

    while (fast->next != NULL && fast->next->next != NULL) {
     

        fast = fast->next->next;

        slow = slow->next;

    }

    return slow;

}
ListNode* reverseList(ListNode* head) {
     

    ListNode* prev = NULL;

    ListNode* curr = head;

    while (curr != NULL) {
      //不断的切断再重组的方式不断迭代形成反转

        ListNode* nextTemp = curr->next;

        curr->next = prev;

        prev = curr;

        curr = nextTemp;

    }

    return prev; //返回逆序后的头指针

}
bool isPalindrome(struct ListNode* head) {
     

    if (head == NULL) {
     

        return true;
    }



    // 找到前半部分链表的尾节点并反转后半部分链表

    ListNode* half = getHalf(head);

    ListNode* secondHalfStart = reverseList(half->next);



    // 判断是否回文

    ListNode* p1 = head;

    ListNode* p2 = secondHalfStart;

    bool result = true;

    while (result && p2 != NULL) {
     

        if (p1->val != p2->val) {
     

            result = false;

        }

        p1 = p1->next;

        p2 = p2->next;

    }



    // 还原链表并返回结果

    half->next = reverseList(secondHalfStart);

    return result;

}

844.比较含退格的字符

没啥可说的,就简单的运用栈的题目。

#define MAXLEN 205
int solve(char* target,char* stack){
     
    int n = strlen(target);
    int top = 0;
    for(int i=0;i<n;i++){
     
        if(target[i]!='#')
            stack[top++] = target[i];
        else{
     
            if(top>0)
                top--;
        }
    }
    stack[top] = '\0';
    return top;
}
bool backspaceCompare(char * s, char * t){
     //简单的栈的运用
    char stack1[MAXLEN];
    char stack2[MAXLEN];
    int len1 = solve(s,stack1);
    int len2 = solve(t,stack2);
    if(len1!=len2)
        return false;
    return strcmp(stack1,stack2)==0;
}

682.棒球比赛

就从左到右的栈模拟

int calPoints(char ** ops, int opsSize){
     
    int stack[opsSize],top = 0;
    for(int i=0;i<opsSize;i++){
     
        if(ops[i][0]=='+'){
     
            int x = stack[top-1]+stack[top-2];
            stack[top++] = x;
        }
        else if(ops[i][0]=='C'){
     
            top--;
        }else if(ops[i][0]=='D'){
     
            int x = stack[top-1]*2;
            stack[top++] = x;
        }else{
     //为数字的情况
            int x = atoi(ops[i]);
            stack[top++] = x;
        }
    }
    int res = 0;
    for(int i=0;i<top;i++)
        res += stack[i];
    return res;
}

1047. 删除字符串中的所有相邻重复项

同栈模拟

char * removeDuplicates(char * s){
     
    int n = strlen(s);
    char* stack = (char*)malloc(sizeof(char)*n);
    int top = 0;
    for(int i=0;i<n;i++){
     
        if(top!=0&&stack[top-1]==s[i]){
     
            top--;
        }
        else
            stack[top++] = s[i];
    }
    stack[top] = '\0';
    return stack;
}

1441. 用栈操作构建数组

这个也是通过栈模拟的题,我发现C是可以把直接const char* 的值用char* 来存下的。也就是直接用char** 申请连续的char* 内存便可以用来存再常量区的字符常量地址。当然我还是用的malloc重新申请的堆内存存的。

#define MAXLEN 200
void solve(char** t,const char* date){
     
    char* q = (char*)malloc(sizeof(char)*10);
    sprintf(q,"%s",date);
    *t = q;
}
char ** buildArray(int* target, int targetSize, int n, int* returnSize){
     
        char** res = (char**)malloc(sizeof(char*)*MAXLEN);
        int top = 0;//top记录char**的实时长度
        int cnt = 0;//cnt记录已经得到的target中的数字情况
        for(int i=1;i<=n;i++){
     //由于单调递增所以不可能出现每个数不做任何操作的过程
            if(target[cnt]==i){
     
                solve(res+top,"Push");
                top++;
                cnt++;
            }else{
     
                solve(res+top,"Push");
                top++;
                solve(res+top,"Pop");
                top++;
            }
            if(cnt==targetSize)
                break;
        }
        *returnSize = top;
        return res;
}

1475.商品折扣后的最终价格

这个根据题目的性质,从右往左更新,然后入栈,只要比当前数字大就pop。

#define MAX_LEN 501
//@栈的基本操作--咋又是单调栈的说。。这次需要从后往前维护一个单调递增的栈
//因为是在 nums[i] 右边的并且距离他最近的小于nums[i]的数,我们只需要从右往左,维护一个比nums[i]小的序列即可--对应的正是单调递增的单调栈!
typedef struct {
     
    int* nums;
    int length;
    int capacity;
} Stack;
void init(Stack* S) {
     
    S->nums = (int*)malloc(sizeof(int) * MAX_LEN);
    S->length = 0;
    S->capacity = MAX_LEN;
}
void Push(Stack* S, int val) {
     
    S->nums[S->length++] = val;
}
bool isEmpty(Stack* S) {
     
    return S->length == 0;
}
int Top(Stack* S) {
     
    if (isEmpty(S))
        return -1;
    return S->nums[S->length - 1];
}
void Pop(Stack* S) {
     
    if (!isEmpty(S)) {
     
        S->length--;
    }
}
//@测试接口
int* finalPrices(int* prices, int pricesSize, int* returnSize){
     
    *returnSize = pricesSize;
    Stack St;
    init(&St);
    int* res = (int*)malloc(sizeof(int) * pricesSize);
    for (int i = pricesSize - 1; i >= 0; i--) {
     
        while (!isEmpty(&St) && prices[Top(&St)] > prices[i])
            Pop(&St);
        res[i] = isEmpty(&St) ? prices[i] : prices[i] - prices[Top(&St)];
        Push(&St, i);
    }
    return res;
}

1544.整理字符串

利用栈进行模拟

char * makeGood(char * s){
     
    int n = strlen(s);
    char* res = (char*)malloc(sizeof(char)*n+1);
    int top = 0;
    for(int i=0;i<n;i++){
     
        if(top!=0){
     //栈不为空的情况
            if((res[top-1]^32^s[i])==0)//第一个异或是大小写反转,第二个异或是判断是否相等
                top--;
            else res[top++] = s[i];
        }else{
     
            res[top++] = s[i];
        }
    }
    res[top] = '\0';
    return res;
}

1598. 文件夹操作日志搜集器

//分三个情况讨论,是前往下一级,还是返回上一级,还是原地不动
int minOperations(char ** logs, int logsSize){
     
    int cnt = 0;
    for(int i=0;i<logsSize;i++){
     
        if(strcmp(logs[i],"../")==0){
     
            if(cnt>0)
                cnt--;
        }else if(strcmp(logs[i],"./")==0){
     
            continue;
        }else{
     
            cnt++;
        }
    }
    return cnt;
}

1614. 括号的最大嵌套深度

int maxDepth(char * s){
     //由于都是有效括号,那这就很简单了
    int n = strlen(s);
    char* stack[n+1];
    int res = 0,top = 0;
    for(int i=0;i<n;i++){
     
        if(s[i]=='('){
     
            stack[top++] = '(';
        }else if(s[i]==')'){
     
            top--;
        }
        res = top>res?top:res;
    }
    return res;
}

150. 逆波兰表达式求值

int evalRPN(char ** tokens, int tokensSize){
     //这题典中之典了属于是
    int stack[tokensSize+1];
    int top = 0;
    for(int i=0;i<tokensSize;i++){
     
        if(!strcmp(tokens[i],"+")){
     
            int x = stack[top-2] + stack[top-1];
            top -= 2;
            stack[top++] = x;
        }else if(!strcmp(tokens[i],"-")){
     
            int x = stack[top-2] - stack[top-1];
            top -= 2;
            stack[top++] = x;
        }else if(!strcmp(tokens[i],"*")){
     
            int x = stack[top-2] * stack[top-1];
            top -= 2;
            stack[top++] = x;
        }else if(!strcmp(tokens[i],"/")){
     
            int x = stack[top-2] / stack[top-1];
            top -= 2;
            stack[top++] = x;
        }else{
     
            stack[top++] = atoi(tokens[i]);
        }
    }
    return stack[0];
}

735. 行星碰撞

开始写的是真的冗余。。。

bool isDash(int x,int y){
     

    return x>0&&y<0;

}

int* asteroidCollision(int* asteroids, int asteroidsSize, int* returnSize){
     

    int* stack = (int*) malloc(sizeof(int)*asteroidsSize);

    int top = 0;

    for(int i=0;i<asteroidsSize;i++){
     

        int t = asteroids[i];

        if(top>0&&isDash(stack[top-1],t)){
     

            bool f = false;

            while(top>0&&isDash(stack[top-1],t)){
     

                if(abs(stack[top-1])<abs(t)){
     

                    top--;

                    f = true;

                }else if(abs(stack[top-1])>abs(t)){
     

                    f = false;

                    break;

                }else{
     

                    top--;

                    f = false;

                    break;

                }

            }

            if(f)

            stack[top++] = t;

        }

        else stack[top++] = t;

    }

    *returnSize = top;

    return stack;

}

后面稍作休整可读性好了很多

int* asteroidCollision(int* asteroids, int asteroidsSize, int* returnSize){
     

    int* stk = (int*)malloc(sizeof(int) * asteroidsSize);

    int top = 0;



    for (int i = 0; i < asteroidsSize; i++) {
     

        stk[top++] = asteroids[i]; // 入栈

        // 处理行星碰撞

        while (top >= 2 && stk[top - 1] < 0  && stk[top - 2] > 0) {
      // 此时才会发生碰撞

            int tmp = stk[top - 1] + stk[top - 2];

            if (tmp == 0){
     

                top -= 2;

            } else if (tmp > 0) {
     

                top--;

            } else {
     

                stk[top - 2] = stk[top - 1];

                top--;

            }

        }

    }

    *returnSize = top;

    return stk;

}

1.两数之和

朴素暴力法

int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
     //两数之和万恶之源
    for (int i = 0; i < numsSize; ++i) {
     
        for (int j = i + 1; j < numsSize; ++j) {
     
            if (nums[i] + nums[j] == target) {
     
                int* ret = malloc(sizeof(int) * 2);
                ret[0] = i, ret[1] = j;
                *returnSize = 2;
                return ret;
            }
        }
    }
    *returnSize = 0;
    return NULL;
}

自己手写简单哈希表解题

#define MAXLEN 49927 
#define T 727 
/*拉链结点*/ 
typedef struct Node{
     
    int index;
    int val;
    struct Node* next;
}node;
/*哈希实体*/ 
typedef struct{
     
    node* nums;
}Set;
/*初始化*/ 
Set* init(){
     
    Set* res = (Set*)malloc(sizeof(Set));
    res->nums = (node*)malloc(sizeof(node)*MAXLEN);
    for(int i=0;i<MAXLEN;i++){
     
        res->nums[i].next = NULL;
    }
    return res;
}
/*简单的哈希函数。。。*/ 
int getPos(int val){
     
    int pos = val%MAXLEN;
    while(pos<0){
     
        pos = (pos + T)%MAXLEN;
    }
    return pos;
}
/*查找*/ 
int find(Set* root,int val){
     
    int pos = getPos(val);
    node* t = root->nums[pos].next;
    while(t!=NULL){
     
        if(t->val==val)
            return t->index;
        t = t->next;
    }
    return -1;
}
/*插入*/ 
void insert(Set* root,int val,int index){
     
    //根据val找链表插入
    int pos = getPos(val);
    node* x = (node*)malloc(sizeof(node));
    x->val = val;
    x->index = index;
    x->next = root->nums[pos].next;
    root->nums[pos].next = x;
}

/*题目测试接口*/ 
int* twoSum(int* nums, int numsSize, int target, int* returnSize) {
     //两数之和万恶之源
    Set* set = init();
    for(int i=0;i<numsSize;i++){
     
        int t = find(set,target-nums[i]);
        if(t!=-1){
     
            int *ret = (int*)malloc(sizeof(int)*2);
            *returnSize = 2;
            ret[0] = t;
            ret[1] = i;
            return ret;
        }
        insert(set,nums[i],i);
    }
    *returnSize = 0;
    return NULL;
}

167. 两数之和 II - 输入有序数组

枚举+二分

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
     
    for(int i=0;i<numbersSize;i++){
     
        int l = i+1,r = numbersSize-1;
        while(l<=r){
     
            int mid = (l+r)/2;
            if(numbers[mid]==target-numbers[i]){
     
                int* ret = (int*)malloc(sizeof(int)*2);
                *returnSize = 2;
                ret[0] = i+1;
                ret[1] = mid+1;
                return ret;
            }
            if(numbers[mid]>target-numbers[i]){
     
                r = mid-1;
            }else{
     
                l = mid+1;
            }
        }
    }
    *returnSize = 0;
    return NULL;
}

双指针

int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
     
    int l = 0,r = numbersSize-1;
    while(l<r){
     
        if(numbers[l]+numbers[r]>target){
     
            r--;
        }else if(numbers[l]+numbers[r]<target){
     
            l++;
        }else{
     
            int* ret = (int*)malloc(sizeof(int)*2);
            *returnSize = 2;
            ret[0] = l+1;
            ret[1] = r+1;
            return ret;
        }
    }
    *returnSize = 0;
    return NULL;
}

806. 写字符串需要的行数

简单遍历

int* numberOfLines(int* widths, int widthsSize, char * s, int* returnSize){
     
    int* ret = (int*)malloc(sizeof(int)*2);
    *returnSize = 2;
    int n = strlen(s);
    int sum = 0;
    int line = 0;
    for(int i = 0;i<n;i++){
     
        if(sum+widths[s[i]-'a']>=100){
     
            line++;
            sum = sum+widths[s[i]-'a']>100?widths[s[i]-'a']:0;
            continue;
        }
        sum += widths[s[i]-'a'];
    }
    ret[0] = sum==0?line:line+1;
    ret[1] = sum==0?100:sum;
    return ret;
}

821. 字符的最短距离

一次遍历暴力法O(n^2)

直接同时找两头

int find(char* s,char c,int index){
     
    int l = 0,r = 0;
    while(index+l>=0||index+r<strlen(s)){
     
        char cmp1 = index+l>=0?s[index+l]:0;
        char cmp2 = index+r<strlen(s)?s[index+r]:0;
        if(cmp1==c){
     
            return -l;
        }
        if(cmp2==c){
     
            return r;
        }
        if(cmp1)l--;
        if(cmp2)r++;
    }
    return -1;
}
int* shortestToChar(char * s, char c, int* returnSize){
     
    int n = strlen(s);
    *returnSize = n;
    int* res = (int*)malloc(sizeof(int)*n);
    int top = 0;
    for(int i=0;i<n;i++){
     
        res[i] = find(s,c,i);
    }
    return res;
}

两次遍历法O(n)

#define INF 0x3f3f3f3f
int* shortestToChar(char * s, char c, int* returnSize){
     
    int n = strlen(s);
    *returnSize = n;
    int* res = (int*)malloc(sizeof(int)*n);
    memset(res,0x3f,sizeof(int)*n);
    int prev = INF;
    for(int i=0;i<n;i++){
     
        if(s[i]==c){
     
            prev = i;
        }
        res[i] = res[i]>abs(prev-i)?abs(prev-i):res[i];
    }
    prev = INF;
    for(int i=n-1;i>=0;i--){
     
        if(s[i]==c){
     
            prev = i;
        }
        res[i] = res[i]>abs(prev-i)?abs(prev-i):res[i];
    }
    return res;
}

832.翻转图像

按照它的规则来,该怎么做就怎么做,但C语言有一坑:这个int** returnColumnSizes 是外面传过来的数组地址,也就是说我们需要通过这个地址修改数组使得returnColumnSizes[0][i]代表第i行的长度。

void reverse(int* t,int st,int ed){
     
    while(st<ed){
     
        t[st] ^= t[ed];
        t[ed] ^= t[st];
        t[st] ^= t[ed];
        st++,ed--;
    }
}
void flip(int* t,int length){
     
    for(int i=0;i<length;i++){
     
        t[i] ^= 1;
    }
}
int** flipAndInvertImage(int** image, int imageSize, int* imageColSize, int* returnSize, int** returnColumnSizes){
     
    *returnSize = imageSize;
    *returnColumnSizes = imageColSize;
    for(int i=0;i<imageSize;i++){
     
        reverse(image[i],0,imageColSize[i]-1);
        flip(image[i],imageColSize[i]);
    }
    return image;
}

你可能感兴趣的:(LeetCode初级算法题,leetcode,链表,算法)