C语言 leetcode 刷题 个人笔记
经过这几天的打磨,也是找到一点门路了,前二天都快把我整绝望了,就简单的算法题,我得想半天,脑子不够用,现在好多了正在努力.
第一题
题目
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的解法
二个链表合并到一个新开辟的一个链表.返回一个新开辟的链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* temp1 = l1;
struct ListNode* temp2= l2;
struct ListNode* ret = (struct ListNode*)malloc(sizeof( struct ListNode));
ret->next = NULL;
ret->val = 0; // 头结点不存数据
struct ListNode* node = NULL;
//如果有一个链表遍历结束结束循环
while(temp1&& temp2){
node = (struct ListNode*)malloc(sizeof( struct ListNode));
node-> next = NULL;
if(temp1 -> val < temp2 -> val){
node -> val = temp1 -> val;
temp1= temp1->next;
}else {
node -> val = temp2 -> val;
temp2= temp2->next;
}
struct ListNode* travesal = ret;
while(travesal ->next){
travesal = travesal-> next;
}
travesal->next = node;
}
//如果temp1(I1)没有遍历结束就继续遍历
while(temp1){
node = (struct ListNode*)malloc(sizeof( struct ListNode));
node-> next = NULL;
node -> val = temp1 -> val;
temp1= temp1->next;
struct ListNode* travesal = ret;
while(travesal ->next){
travesal = travesal-> next;
}
travesal->next = node;
}
//如果temp2(I2)没有遍历结束就继续遍历
while(temp2){
node = (struct ListNode*)malloc(sizeof( struct ListNode));
node-> next = NULL;
node -> val = temp2 -> val;
temp2= temp2->next;
struct ListNode* travesal = ret;
while(travesal ->next){
travesal = travesal-> next;
}
travesal->next = node;
}
//二个链表中的节点全部进入新开辟的链表
//因为头结点不保存数据 ret -> next作为头结点返回
struct listNode * res = ret -> next;
free(ret);
return res;
}
2.用递归实现
说实话光看代码的话我实在看不懂,只能画图理解;我画了一张图
/*
*二个将两个升序链表合并为一个新的升序链表并返回
*
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
//终止条件:l1或者l2 == NULL 结束递归
if(l1 == NULL){
return l2;
}
if(l2 == NULL){
return l1;
}
//如果当前l1节点的数据小于l2节点的数据
if(l1->val < l2-> val){
l1-> next = mergeTwoLists(l1-> next ,l2);
return l1;
} //否则(当前l1节点的数据小于l2节点的数据)
else{
l2 -> next = mergeTwoLists(l1,l2-> next);
return l2;
}
}
l1 l2后面是节点的数据第一个元素是当前指向的节点数据只要链接到一个节点 ,就能抓到这个节点以后的数据
3.暴力解法
//设置一个不存数据的头结点链接二个链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* head = (struct ListNode* )malloc(sizeof(struct ListNode));
struct ListNode* pointer = head;
while(l1&&l2){
if(l1-> val < l2->val){
pointer->next = l1;
l1=l1->next;
}else{
pointer-> next = l2;
l2 = l2-> next;
}
pointer = pointer -> next;
}
pointer ->next = l1 == NULL?l2:l1;
struct ListNode*ret = head->next;
free(head);
return ret;
}
总结
这个题做是简单的但是这个用递归实现的有点难以理解,我用来半天的时间才理解了 ,我对递归算法还是停留在给我个递归函数,必须画图才能理解,让我写出一个递归函数写不出来,