链表系列
题是很简单的题 (
leetcode237删除节点
俺当时看到题第一反应就是。噢 删除呀。不就是p->next=p->next->next?用q来取代p->next ,最后再把q free掉。嗯。这就是应激反应,(压根不看题的傻逼
注意题干。传入函数的唯一参数为要被删除的节点。
上边这个p是你要删除的节点的前一个结点,这显然是不符合的。
想让大家想一想,如果你就是这个节点,我这个做题人啊,要杀了你,这是我接到的命令,你怎么办呢??
好,一个戏剧就出现了。
把自己包装成另一个人,告诉杀手,我已经不是我了,你杀我没有用,你把他杀了就行。反正我已经跟他一模一样了,杀了他。
这就像狸猫换太子 哈哈哈
于是,我们就可以想到。我们把我们要删除的那个节点,包装它的成下一个节点,再free它的下一个节点,不就好了咩。
所以我们可以得到。
node->vail=node->vail->vail.//把我的值跟你一样
node->next=node->next->next//把我的next域也跟你一样
这个结束后,我莫名其妙想起来一句台词,从前的那个xxx,已经死了
然后free 就成!
今天拯救了一个该死没死成的节点。可是它已经不是原来的它了,那跟死掉也没有区别。它代替了它的下一个节点工作着。
如何让自己在世界上消失,但又不死? —— 将自己完全变成另一个人,再杀了那个人就行了。
86分隔链表。
当时我第一反应是想起来有一次培训作业,让把0都放前面 还有那个奇数在前,偶数在后。所以双指针的思想就是这么涌上心头的!
但实际操作过程中,种种磕绊(谁让我菜
其实链表还蛮像火车的,不知道大家有看过托马斯小火车么///
如果你想让这一列火车根据某种规则交换顺序,你是否可以这样呢。
不好意思本腐女突然很想拿这个做例子。
假如,嗯,这是一个gay的相亲会。0和1配对。我们首先把1和0分开。
那好,你是0,你站左边这一队,你是1?稀有!站右边!!
就这样排呀排呀 0都到左边了,1都到右边了,两队站好了。
然后负责人说1站前面,0站后边,好。两队就合成一队了。接下来就配对吧hhh
所以这个题的思想就很显而易见了,利用两个指针,再创建两个链表,也就是排两队。让比x大的排一队,其余的排另一队,然后再合成一队。就完成了这个题。
注意蛤 你这两队要想合并,都要有头有尾的。
p队开头是p 利用p1遍历。
struct ListNode* partition(struct ListNode* head, int x){
if(!head||!head->next)
return head;
struct ListNode*p=(struct ListNode*)malloc(sizeof(struct ListNode)),*p1;
struct ListNode*q=(struct ListNode*)malloc(sizeof(struct ListNode)),*q1;
p1=p;
q1=q;
p1->next=NULL;q1->next=NULL;//
while(head)
{
if(head->val<x)
{
p1->next=head;
p1=p1->next;
}
else
{
q1->next=head;
q1=q1->next;
}
head=head->next;
}
p1->next=q->next;
q1->next=NULL;
return p->next;
}
还要提示一个易错点,我一次提交错误就是这个原因。
必须先进行q1->next=NULL;再把链表p和链表q连在一起。其实我写的有点赘余。
解释一下为什么
比如【1,3,5,6,2】这个链表,假设 x=3,则可得到两个链表分别是【1,2】和【3,5,6】,但此时右链表的尾部,即6的尾部仍指向2,如果不把右链表的尾部置为None,最后就会得到 1->2->3->5->6->2 这个链表,在节点2处成环。因此必须将右链表尾部手动置为NULL,实现断链,最后得到 1->2->3->5->6->NULL。
END
剑指 Offer 06. 从尾到头打印链表
解法1:常规
我的 ,普普通通的解法 没有什么新奇的,都能想到
int* reversePrint(struct ListNode* head, int* returnSize){
if(head==NULL)
{
*returnSize=0;
return NULL;
}
struct ListNode *p=head;
int j=0;
while(p)
{
p=p->next;
j++;
}
int *a=(int *)malloc(sizeof(int)*j);
for(int i=j-1;i>=0;i--)
{
a[i]=head->val;
head=head->next;
}
*returnSize=j;
return a;
}
框框部分本来我写的int a[j];
警示:不要用变量作为数组的大小。哪怕你这个j已经计算出来也不行。得用malloc写。
解法2:栈
int* reversePrint(struct ListNode* head, int* returnSize){
*returnSize=0;
if(head==NULL)
{
return NULL;
}
int stack[10000];
int top=-1;//栈顶
while(head)
{
stack[++top]=head->val;
head=head->next;
}
int *a=(int *)malloc(sizeof(int)*(top+1));
while(top!=-1)//弹栈
{
a[(*returnSize)++]=stack[top--];
}
return a;
}
解法3:用头插法对链表进行逆置
leetcode默认头节点是第一个节点 emmm 就是它是有值的
int* reversePrint(struct ListNode* head, int* returnSize){
*returnSize=0;
if(head==NULL)
{
return NULL;
}
struct ListNode *p,*temp;
p=head;
int j=1;
while(head->next)
{
temp=head->next;
head->next=temp->next;
temp->next=p;
p=temp;
j++;
}
*returnSize=j;
int *a=(int *)malloc(sizeof(int)*j);
for(int i=0;i<j;i++)
{
a[i]=p->val;
p=p->next;
}
return a;
}
剑指 Offer 24. 反转链表
第一次的错误解法:超时!
my思路。利用头插法再创建一个链表,遍历原链表,让链表的每一个元素头插在新链表里,实现反转。
But直接超时了。。。。啊啊
发现了 我是傻逼。我又把它连回去了
修正如下
正确代码如上。仔细斟酌待定。
解法1:双指针
作者:huwt
链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-yi-dong-de-shuang-zhi-zhen-jia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
妙极了
struct ListNode* reverseList(struct ListNode* head)
{
struct ListNode *cur=NULL;
struct ListNode *pre=head;
while(pre)
{
struct ListNode *t=pre->next;
pre->next=cur;
cur=pre;
pre=t;
}
return cur;
}
注意用t先保存pre的next地址
链表看不懂代码就手动模拟画图