这种方法很容易理解,实现也比较方便,只需要用三个指针,分别为前一个位置,当前位置,后一个位置来完成就可以实现
struct ListNode* reverseList(struct ListNode* head)
{
// 改变原链表的指向
struct ListNode* cur=head;
if(head==NULL)
{
return head;
}
struct ListNode* nnext=head->next;
struct ListNode* pre=NULL;
while(cur)
{
cur->next=pre;
pre=cur;
cur=nnext;
if(nnext!=NULL)
{
nnext=nnext->next;
}
}
head=pre;
return head;
}
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* newhead = NULL;
struct ListNode* cur = head;
while(cur)
{
struct ListNode* next = cur->next;
//头插新节点,更新头
cur->next = newhead;
newhead = cur;
cur = next;
}
return newhead;
}
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;
}
struct ListNode* middleNode(struct ListNode* head)
{
//方法一:记录总共多少个节点,然后找到它的一半的那个节点
int n=0;
struct ListNode* tail=head;
if(tail!=NULL)
{
n=0;
}
else
{
return NULL;
}
while(tail)
{
n++;
tail=tail->next;
}
int middlenum=(n/2)+1;
struct ListNode* middle=head;
while(--middlenum)
{
middle=middle->next;
}
return middle;
}
方法一这种方法容易想出,也不算太复杂,那有没有更快的方法了?
下面我们迎来了一种全新的方法快慢指针,在这道题目里面,我们让快指针一次走两步,慢指针一次走一步,当快指针走到尾节点时,慢指针此时恰好在中间节点,这个道理也很容易想明白,因为快指针走的速度是慢指针的两倍,所以当快指针到尾时,慢指针才会在中间。快慢指针这种全新的方法在很多其他题目里面也非常的好用
struct ListNode* slow=head;
struct ListNode* quick=head;
while(quick!=NULL&&quick->next!=NULL)
{
slow=slow->next;
quick=quick->next->next;
}
return slow
这种方法也是受前一题中间节点的那种计数的方法影响,看看这边是否也可以,但写了一下发现总是过不了,代码感觉也没有问题,希望懂得小伙伴可以帮忙看看
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
int n=0;
struct ListNode* tail=pListHead;
struct ListNode* ans=pListHead;
while(tail)
{
n++;
tail=tail->next;
}
if(k>n&&k<=0)
{
return NULL;
}
else
{
int find=n-k+1;
while(--find)
{
ans=ans->next;
}
return ans;
}
}
我们可以让快的指针先走k步,以此来达到此目的,所以说快慢指针在有些题中用过是很大的
struct ListNode*slow=pListHead;
struct ListNode* fast=pListHead;
while(k--)
{
if(fast)
{
fast=fast->next;
}
else
{
return NULL;
}
}
while(fast)
{
fast=fast->next;
slow=slow->next;
}
return slow;
在看完题目之后,我对这题大概就知道解法了,可以创建一个新的链表,然后以此挑选小的来当来,这里面要注意如果移动,以及一些边界情况
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2)
{
struct ListNode*newhead=NULL;
struct ListNode* p1=l1;
struct ListNode* p2=l2;
struct ListNode*tail=NULL;
if(p1==NULL&&p2==NULL)
{
return NULL;
}
else if(p1!=NULL&&p2==NULL)
{
return p1;
}
else if(p2!=NULL&&p1==NULL)
{
return p2;
}
if(p1->val<p2->val)
{
newhead=p1;
p1=p1->next;
}
else
{
newhead=p2;
p2=p2->next;
}
tail=newhead;
while(p1&&p2)
{
if(p1->val<p2->val)
{
tail->next=p1;
tail=p1;
p1=p1->next;
}
else
{
tail->next=p2;
tail=p2;
p2=p2->next;
}
}
if(p1==NULL)
{
tail->next=p2;
}
if(p2==NULL)
{
tail->next=p1;
}
return newhead;
}
在看完题目后,我第一反应是建立一个新的链表,然后将小于x的尾插进去,然后想着想着,发现单单建立一个是不行的,要两个链表才可以,一个存放小于x的,一个存放大于x等于x的,但我在这小的过程中犯了一个很重要的错误,就是链表节点之间的指向,如果你分下来分,换句话说,你没有在一个while循环里面把大于等于x和小于x的元素分开,这样会导致元素之间的指向关系混乱,下面大家也可以看看这段代码,以此为戒。
struct ListNode* newhead=NULL;
struct ListNode* tail=NULL;
struct ListNode* cur=pHead;
struct ListNode* bighead = NULL;
struct ListNode* bigtail = NULL;
while(cur)
{
if(cur->val<x)
{
newhead=cur;
tail=newhead;
break;
}
else
{
cur=cur->next;
}
}
if(cur==NULL)
{
return pHead;
}
else
{
cur=cur->next;
while(cur)
{
if(cur->val<x)
{
tail->next=cur;
tail=cur;
cur=cur->next;
}
else
{
cur=cur->next;
}
}
}
tail->next=NULL;
cur=pHead;
while(cur)
{
if(cur->val>x||cur->val==x)
{
bighead=cur;
bigtail=bighead;
break;
}
else
{
cur=cur->next;
}
}
if(cur==NULL)
{
return pHead;
}
else
{
cur=cur->next;
while(cur)
{
if(cur->val>x||cur->val==x)
{
bigtail->next=cur;
bigtail=cur;
cur=cur->next;
}
else
{
cur=cur->next;
}
}
}
bigtail->next = NULL;
tail->next = bighead;
return newhead;
if(pHead == NULL)
return NULL;
struct ListNode* lessHead, *lessTail,*greaterHead, *greaterTail;
//创建链表表头
lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));
greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* cur = pHead;
while(cur)
{
//小于x的尾插到lessTail
if(cur->val < x)
{
lessTail->next = cur;
lessTail = lessTail->next;
}
//大于等于x的尾插到greaterTail
else
{
greaterTail->next = cur;
greaterTail = greaterTail->next;
}
cur = cur->next;
}
//链接两个链表
lessTail->next = greaterHead->next;
greaterTail->next = NULL;
//获取表头
pHead = lessHead->next;
free(lessHead);
free(greaterHead);
return pHead;
其实当我实在是修改不了那段bug代码后,看正确代码的时候,发现还是应该在写代码前把思路理顺,想想怎么写才是最优化的,是什么问题导致我这个bug的,我可不可以避开这个问题了?如果我在写的时候或者写之前把这些想明白,可能也就不会写出那段bug代码。