小编是双非本科大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)
此前博客点我!点我!请搜索博主 【知晓天空之蓝】
乔乔的gitee代码库(打灰人 )欢迎访问,点我!
非科班转码社区诚邀您入驻
小伙伴们,打码路上一路向北,背后烟火,彼岸之前皆是疾苦
一个人的单打独斗不如一群人的砥砺前行
这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!!
社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)
直达: 社区链接点我
你觉得今天打打球没关系,下次你就会觉得明天躺在宿舍玩玩手机也没关系,不要低估你的实力,却不能高估你的毅力,只有优秀成为一种习惯你才不会优柔寡断,唯唯诺诺,当你还没有成功的那一刻,你什么都不是,只有成功之后,你放屁都是香的,你之所以没有这种感觉就是因为你还没有成功。 -------摘自托马斯-酷涛大佬原文
链接:移除链表元素
题目:给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点
示例 :
输入:head = [1,2,3,2,1], val = 2
输出:[1,3,1]
思路:
我的评价是有手就行,就相当于链表的删除操作,进行遍历,遍历过程中找到目标值进行覆盖就行,注意一下这里我们采用哨兵位节点,也称为哑节点,开辟出来指向链表头节点,可以使对头节点的操作变简单很多,这个哨兵位节点的值可以不考虑,他只是用来攀搭头结点的舔狗(呜呜)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
dummyHead->next = head;
struct ListNode* curr = dummyHead;//定义哨兵位节点
while (curr->next) {
if (curr->next->val == val) {
curr->next = curr->next->next;//遍历到目标点进行覆盖
}
else
{
curr = curr->next;
}
}
head = dummyHead->next;
free(dummyHead); //有借有还,记得归还哨兵位节点和申请的空间
return head;
}
链接:反转链表
题目:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表
示例 :
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
思路:
1.创建一个新的中间节点我命名为 next ,将当前节点的下一个节点存放在next 节点中
2.链接 next 和当前节点,将 next 指向 当前节点实现反转,将原来指向下一节点的内容销毁掉(头部指向NIULL即可);
3.重复上述过程即可
以上是整体思路实现,而代码实现我们有两条路可以走,分别是迭代和递归,实现思路是一样的:
迭代:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode* next = NULL;
struct ListNode* prev = NULL;
while(head)
{
next = head->next;
head->next = prev;
prev = head;
head = next;
}
return prev;
}
递归:
递归又分为了向前递归和向后递归,一般采用从前向后递归:
struct ListNode* reverse(struct ListNode* cur,struct ListNode* prev)
{
if(cur==NULL)
{
return prev;
}
struct ListNode* next = cur->next;
cur->next = prev;
return reverse(next,cur); //可以与双指针法对比,其实逻辑是一样的,只是用递归实现而已
}
struct ListNode* reverseList(struct ListNode* head)
{
return reverse(head,NULL);
}
从后向前递归:
struct ListNode* reverseList(struct ListNode* head)
{
if(!head || !head->next)
return head;
struct ListNode* cur = reverseList(head->next);//反转第二个节点后的所有节点
head->next->next = haed;//反转第二个节点与头节点
head->next = NULL;//头节点处理
return cur;
}
链接:链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点,如果有两个中间结点,则返回第二个中间结点。
奇数个返回中间节点:
偶数个返回了两个节点中的后一个:
思路:
方法一就是老老实实去遍历链表,算出链表长度,再找出中间节点位置,走过去返回他,属于暴力求解,笨且效率不高,这里就不做代码展示;
方法二巧用快慢指针,如下图:
我们定义两个指针,慢指针一次走一步,快指针一次走两步,不管链表节点数是奇是偶,慢指针最后必定落在中间节点;当链表节点为偶数个时,最后快指针将落在最后一个节点上,所以只需要判断快指针的 next 节点为不为空即可
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* guard = malloc(sizeof(struct ListNode));
guard->next = head;//定义哨兵位节点
struct ListNode* fast = guard;
struct ListNode* slow = guard;
while(fast)
{
slow = slow->next;//慢指针一次走一步
if(fast->next)
{
fast = fast->next->next;//快指针一次走两步
}
else
{
return slow;
}
}
return slow;
}
今天就先到这里吧,摸了家人们。