Leetcode刷题记录
最近开始在Leetcode上做题,先从简单题做起慢慢加大难度吧。
这里是过程中一些问题的记录。
9.22
简单:
538. 把二叉搜索树转换为累加树
二叉搜索树:一种二叉树,其中根节点大于它所有左子树中的结点,小于所有右子树中的结点。
自己写的时候主要是二叉搜索树的建立、遍历按照右子树->根节点->左子树的顺序,一边遍历一边统计val,再加上去。
int sum; int dfs(struct TreeNode *root){ struct TreeNode *p=root; if(!p) return 0; sum+=dfs(p->right); sum+=p->val; p->val=sum; dfs(p->left); return 0; } struct TreeNode *convertBST(struct TreeNode* root){ sum=0; dfs(root); return root; }
LCP 22. 黑白方格画
一道简单数论题(最开始以为是搜索写了几十行越写越复杂,然而根本没有那么复杂。。)
注意所有格子都取的情况的判断。(自己写的时候没有考虑到这种情况,以后还需要想的细致一点)
int fac(int n){ int ans=1; for(int i=1;i<=n;++i){ ans=ans*i; } return ans; } int C(int n,int m){ return fac(n)/(fac(n-m)*fac(m)); } int paintingPlan(int n, int k){ int ans=0; if(n*n==k) return 1; for(int i=0;i<n;++i){ for(int j=0;j<n;++j){ if((i+j)*n-i*j==k){ ans+=C(n,i)*C(n,j); } } } return ans; }
剑指 Offer 42. 连续子数组的最大和
这道题有O(n^2),O(nlogn),O(n)的做法,代码实现上应该是O(nlogn)最复杂(需要用到归并的思想),O(n)的做法有点像简单的动归。
int max(int a,int b){ return a>b?a:b; } #define inf 0x80000000 int maxSubArray(int* nums, int numsSize){ int f[numsSize],mmax; for(int i=0;i<numsSize;++i) f[i]=inf; f[0]=nums[0];mmax=nums[0]; for(int i=1;i<numsSize;++i){ f[i]=max(f[i-1]+nums[i],nums[i]); mmax=max(mmax,f[i]); } return mmax; }
9.23
简单
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
一道简单题,用两个指针一头一尾地扫,遇到偶数和奇数就把这两个数交换。
但是有几点收获:
1. returnSize一定要赋值!!(每个参数都是有用的) 这个一开始没有赋值导致一直执行出错
2.用C语言写swap函数时,一定要采用*(指针传值方式),调用函数的时候参数使用变量的地址,如果用&传值会报错。(C++可以,但是C不行)
void swap(int& a,int& b){ int t=a; a=b;b=t; }
⬆在C++中是成立的,但是在C中不行
C可以采用下面的方式:
void swap (int *a,int *b){ int temp=*a; *a=*b; *b=temp; }
完整代码:
#include<stdlib.h> void swap (int *a,int *b){ int temp=*a; *a=*b; *b=temp; } int* exchange(int* nums, int numsSize, int* returnSize){ //What's the purpose of *returnSize? int *b=(int *)malloc(sizeof(int)*numsSize); *returnSize=numsSize; int l=0,r=numsSize-1; while(l<r){ while(l<numsSize&&(nums[l]&1)) ++l; while(r>=0&&(!(nums[r]&1))) --r; if(l>r||l>=numsSize||r<0) break; swap(&nums[l],&nums[r]); } for(int i=0;i<numsSize;++i) b[i]=nums[i]; return nums; }
简单
剑指 Offer 58 - I. 翻转单词顺序
#include<stdlib.h> #include<string.h> char* reverseWords(char* s){ int n=strlen(s); char *s1; s1=(char*)malloc(sizeof(char)*(n+1)); //计算出s1的内存 sizeof(char)*(n+1)!!!! for(int i=0;i<n;++i) s1[i]=s[n-i-1]; //reverse int cnt=0; for(int i=0;i<n;++i) printf("%c",s1[i]); printf("\n"); for(int i=0;i<=n;++i){ if(i>0&&s1[i]==' '&&s1[i-1]!=' '){ for(int j=i-1;j>=0&&s1[j]!=' ';--j) s[cnt++]=s1[j]; s[cnt++]=' '; } else if(i>0&&i==n&&s1[i-1]!=' '){ for(int j=i-1;j>=0&&s1[j]!=' ';--j) s[cnt++]=s1[j]; } } if(cnt>=1) if(s[cnt-1]==' ') cnt--; //注意空格结尾的情况 有数组的时候一定要注意数组越界的判断!!! s[cnt++]=0; return s; }
传入的字符串指针也可以用strlen/sizeof()读长度 注意一个非常标准的以空格结尾的情况(去掉行末空格)。
注意数组越界问题(Leetcode在这方面真的很严格了)
s1的长度需要是sizeof(s)+1 !!!!(因为末尾的0
简单
链表
#include<stdio.h> #include<stdlib.h> struct ListNode { int val; struct ListNode *next; }; struct ListNode *list; struct ListNode* getKthFromEnd(struct ListNode* head, int k){ struct ListNode *p=head; int n=0; while(p) {n++;p=p->next;} p=head; for(int i=1;i<=n-k;i++) { p=p->next; } return p; } struct ListNode *append(struct ListNode *list,int val){ struct ListNode *newone=(struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode *p=list; newone->val=val,newone->next=NULL; if(p==NULL) list=newone; else{ while(p->next) p=p->next; p->next=newone; } return list; } int main(){ int n;scanf("%d",&n); struct ListNode *list=NULL; for(int i=0;i<n;++i){ int x;scanf("%d",&x); list=append(list,x); } list=getKthFromEnd(list,2); printf("%d",list->val); return 0; }
倒数第k个,也就是正数第n-k+1个,已经不会写链表了(误

浙公网安备 33010602011771号