目录
1.删除链表中倒数第n个结点
【题目】
【分析】
法1:计算链表长度
int getlength(struct ListNode* head){
int i=0;
while(head!=NULL){
head=head->next;
i++;
}
return i;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
int len=getlength(head);
struct ListNode* L=malloc(sizeof(struct ListNode));
L->val=0;
L->next=head;
struct ListNode *cur=L;
for(int i=1;i<len-n+1;i++){
cur=cur->next;
}
cur->next=cur->next->next;
struct ListNode* ans=L->next;
free(L);
return ans;
}
法2:双指针
struct ListNode* removeNthFromEnd(struct ListNode* head,int n){
struct ListNode* L=malloc(sizeof(struct ListNode));
L->val=0;
L->next=head;
struct ListNode* p=L;//p是前驱结点
struct ListNode* q=L;
for(int i=0;i<n+1;i++){
q=q->next;
}
while(q){
p=p->next;
q=q->next;
}
struct ListNode* delNode = p->next;
p->next=delNode->next;
struct ListNode* ans=L->next;
free(L);
return ans;
}
2.字符串的排列
【题目】
【分析】
bool checkInclusion(char* s1, char* s2) {
int n = strlen(s1), m = strlen(s2);//n,m分别对应1,2的长度
if (n > m) {//如果字符串1大于字符串2的长度直接返回false
return false;
}
int cnt[26];//建立小写字母数组
memset(cnt, 0, sizeof(cnt));//为每个字母对应的数组空位置0
for (int i = 0; i < n; ++i) {
--cnt[s1[i] - 'a'];//将字符串1内的字符进行统计(按负数统计)
}
int left = 0;
for (int right = 0; right < m; ++right) {
int x = s2[right] - 'a';//获取right对应字母在cnt中的位置
++cnt[x];//计数加一
while (cnt[x] > 0) { //该字母数在字符串2内的数目大于字符串1 大于0的都是s2有s1没有的字符
--cnt[s2[left] - 'a']; //left对应字母在cnt中计数减1
++left; //left右移
}
if (right - left + 1 == n) { //若左右指针间长度等于s1的长度
return true; //返回true
}
}
return false;
}
3.图像渲染
【题目】
【分析】
imageSize的意思是行的长度,
imageColSize对应每一列的长度(注意是数组),
sr为选定值的x坐标
sc为选定值的y坐标
类似于递归,由于给出初始的块,并且已知初始的颜色,且该图是一个二维图,所以只有上下左右四个邻接。
实现邻接:假如初始的坐标为[1,1],那么和初始坐标邻接的就是(1,0),(1,2),(0,1),(2,1)
为了实现坐标的更迭,定义相应的函数来更迭坐标的位置,该题中可以设dx,dy来实现。
设dx[4]={0,0,-1,1};dy[4]={1,-1,0,0};
之后坐标只要将其自身的x+dx[i],y+dy[i],就可以实现同时四个方向的搜索,类似于递归的找法,直到x出规定范围,y出规定范围,就可以返回原图,实现颜色替换。
// const int dx[4]={0,0,-1,1};
// const int dy[4]={1,-1,0,0};
// //定义用于之后的查找,由于是找出邻接的四个单位,
// //所以就是(x,y+1)(上),(x,y-1)(下),(x-1,y)(左),(x+1)(右)。
// //tips:为了能够完成该操作,在对应的dx[i]和对应的dy[i]中要实现对应的数,下面的A中可以看到
// void dfs(int **image,int imageSize,int *imageColSize,int x,int y,int curcolor,int newcolor)
// {
// if(x<0||x>=imageSize||y<0||y>=imageColSize[0]){
// return;
// }
// //判断是否越界,如果越界直接返回。
// //tips:imageColSize[0]不能漏掉[0],因为imageColSize原名imagecolumnsize,
// //对应每列的长度并且在输入值时,输入的就是数组,所以要用它本身的元素
// if(image[x][y]==curcolor)
// {
// image[x][y]=newcolor;
// //替换颜色
// for(int i=0;i<4;i++)
// {
// int nx=x+dx[i];
// int ny=y+dy[i];
// //A操作,i=0,1,2,3分别对应上下左右新定义nx,ny,并且判断nx,ny是否越界用于下面的深度优先查找
// if(nx>=0&&nx<imageSize&&ny>=0&&ny<imageColSize[0])
// {
// dfs(image,imageSize,imageColSize,nx,ny,curcolor,newcolor);
// }
// }
// }
// return;
// }
// int** floodFill(int** image, int imageSize, int* imageColSize, int sr, int sc, int newColor, int* returnSize, int** returnColumnSizes){
// *returnSize=imageSize;
// *returnColumnSizes=imageColSize;
// if(image[sr][sc]!=newColor){
// dfs(image,imageSize,imageColSize,sr,sc,image[sr][sc],newColor);
// }
// //要先判断是否和新颜色相同,用例中有原来就是新颜色不需要更改的例子
// return image;
// }
4.合并两个有序链表
【题目】
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
【分析】
1.递归
2.迭代
//递归
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){
if(list1==NULL){
return list2;
}
if(list2==NULL){
return list1;
}
//list1 , list2 都存在的情况,使用递归进行求解
if(list1->val < list2->val) {
list1->next = mergeTwoLists(list1->next, list2);
return list1;
}
else {
list2->next = mergeTwoLists(list1, list2->next);
return list2;
}
}
//双指针迭代
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* l3 = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode* p1 = l1, * p2 = l2;
struct ListNode* r3 = l3;
while(p1 && p2){
if((p1 -> val) <= ( p2 -> val)){
r3 -> next = p1;
r3 = p1;
p1 = p1 -> next;
}
else{
r3 -> next = p2;
r3 = p2;
p2 = p2->next;
}
}
if(!p1)
{ r3 -> next = p2 ; }
else if(!p2)
{ r3 -> next = p1; }
return l3->next;
}
5.反转链表
【题目】
【分析】
迭代,递归
//迭代
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* prev=NULL;
struct ListNode* cur=head;
while(cur){
struct ListNode* next=cur->next;
cur->next=prev;
prev=cur;
cur=next;
}
return prev;
}
//递归
struct ListNode* reverseList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* newHead = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return newHead;
}