1. 题目:力扣237删除链表中的节点
思考:
从链表里删除一个节点 node 的最常见方法是修改之前节点的 next 指针,使其指向之后的节点。但是这道题我们无法访问我们想要删除的节点(node) 之前的节点.
void deleteNode(struct ListNode* node)
看它传入的参数是一个节点,所以我们只需要将想要删除的节点的值替换为它后面节点中的值,然后删除它之后的节点就可以了。但是要注意,题目中有提示(给定的节点为非末尾节点并且一定是链表中的一个有效节点)所以我们才可以用->next->next
,不然是不行的。
代码:
void deleteNode(struct ListNode* node) {
node->val = node->next->val;
node->next = node->next->next;
return ;
}
2. 题目力扣203移除链表元素
思考:
删除节点的步骤:1.找到该节点的前一个节点,使它的next指向该节点的后一个节点
注意:
我这里设了一个虚拟头节点,定义前一个指针pre,并且用于最后输出链表。
(其实一般情况下,末尾节点也可以用->next->next
。但是要判断这个节点的上一个是不是NULL)。
代码:
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode *p = head;
struct ListNode *sen = (struct ListNode *)malloc(sizeof(struct ListNode));
sen->next = head;
struct ListNode *pre = sen;
while(p) {
if(p->val == val) {
pre->next = p->next;
p = p->next;
}else{
pre = p;
p = p->next;
}
}
return sen->next;
}
3. 题目力扣19删除链表的倒数第N个节点
思考:
这道题主要运用了快慢指针的方法,让快指针先走k步,慢指针走剩余的(n-k)步,最后就指向了倒数第n个节点。
代码:
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNode *fast = head, *slow = head;
while (fast) {
if (n >= 0) { //快指针先走k步
fast = fast->next;
n--;
} else{ //走剩余的(n-k)步
fast = fast->next;
slow = slow->next;
}
}
if(n == 0) {
return head->next;
}
slow->next = slow->next->next;
return head;
}
4. 题目:力扣141环形链表
思考:
慢指针每次移动一步,而快指针每次移动两步。两者相遇即证明链表有环。
需要注意的是while的条件while(f!= NULL && f->next != NULL)
,一定都要有,否则的话就会指向NULL报错。
代码:
bool hasCycle(struct ListNode *head) {
struct ListNode *s = head, *f = head;
if(head == NULL) return 0;
while(f!= NULL && f->next != NULL){
s = s->next;
f = f->next->next;
if(s == f) {
return 1;
}
}
return 0;
}
5. 题目 反转链表力扣206
思考:
反转链表的思路,设置三个指针,另设一个空指针q,一个指针nex, 然后依次往后移动指针,直到第二个结点为空结束,类似于头插的思路来反转链表。感兴趣还可以看看这篇反转链表
代码:
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *q = NULL, *p = head, *nex;
while(p != NULL) {
nex = p->next; //核心代码
p->next = q;
q = p;
p = nex;
}
return q;
}
6. 题目:回文链表 力扣234
思考:
这道题就是先运用快慢指针找出中间节点,然后反转前面的链表,最后进行比较。
代码:
bool isPalindrome(struct ListNode* head){
if(head == NULL || head->next == NULL) {
return true;
}
struct ListNode *slow = head, *fast= head, *res = NULL;
while(true) {
if(fast == NULL) { //判断链表个数为偶数的时候
break;
}if(fast->next == NULL) { //判断链表个数为奇数
head = head->next;
break;
}
fast = fast->next->next; //快慢指针找出中间节点
head = head->next;
slow->next = res;
res = slow;
slow = head;
}
while( head != NULL && res != NULL) { //反转后比较两个链表
if(head->val != res->val) {
return false;
}
head = head->next;
res = res->next;
}
return true;
}