《力扣刷题笔记》除自身以外数组的乘积&& 复制带随机指针的链表

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

        left=left*nums[i-1];
    answer[i]=left;
}


倒数第一个元素的右积等于1


倒数第二个元素的右积等于倒数第一个元素的右积乘于倒数第一个元素


倒数第三个元素的右积等于倒数第二个元素的右积乘于倒数第二个元素。


以此类推。。。。。。


因此我们可得出求每个元素的右积方法:



int right=1;
for(i=numsSize-1;i>=0;i–)
{
if(i<numsSize-1)
right=rightnums[i+1];
answer[i]
=right;
}


参考代码:



int* productExceptSelf(int* nums, int numsSize, int* returnSize)
{
int* answer=(int*)malloc(sizeof(int)numsSize);
int i=0;
int left=1;
int right=1;
for(i=0;i<numsSize;i++)
{
if(i>0)
left=left
nums[i-1];
answer[i]=left;
}
for(i=numsSize-1;i>=0;i–)
{
if(i<numsSize-1)
right=rightnums[i+1];
answer[i]
=right;
}
*returnSize=numsSize;
return answer;
}



思路总结:

两步走:

第一步:

开辟一个新数组,将原数组每个元素的左积求出(如果为第一个数组元素,那么它的左积就是一)

并把它们的左积对应放入新数组中。

第二步:

求原数组每个元素的右积,求出后,乘于对应新数组的元素,并把乘后的结果放入对应新数组元素中。

三、复制带随机指针的链表

难度:中等

题目:给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。返回复制链表的头节点。

用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val,random_index] 表示:

val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。
你的代码 只 接受原链表的头节点 head 作为传入参数。

来源:力扣(LeetCode)

题意:

以该链表为例,我们需要复制一份一模一样的该链表,类似于c++中的深拷贝。

说白了,就是原节点指向某个原节点,那么拷贝节点的random必须指向某个原节点的拷贝节点。

原7的next指向原13,即拷贝的7要指向拷贝的13,原7的random指向NULL,即拷贝的7的random要指向NULL。原13的random指向原7,即拷贝13的random要指向拷贝7.

将7、13、11、10、1、NULL拷贝出来一份,用next连接起来容易。但它们random怎么指向呢?

图解:

连接新链表与拷贝链表:

我们只有原链表的头指针,我们知道原7的random是指向NULL,那么拷贝7的random指向NULL是容易的,原13的random是指向7的,我们只知道random指向的地址空间。

即我们只知道0x11 31 24 31,而这块空间和新拷贝的空间是无关联的,这并不能很好的帮助我们拷贝13该指向拷贝链表的哪块地址。

所有比较好的办法是将原链表和新拷贝链表连接起来。

图解:

参考代码:

    Node* cur=head;
    //在原节点后拷贝节点并连接起来。
    while(cur)
    {
        Node* newnode=(Node*)malloc(sizeof(Node));
        newnode->val=cur->val;
        newnode->next=cur->next;
        cur->next=newnode;
        cur=newnode->next;
    }

分配拷贝链表的random指向:

当我们知道原7的random指向NULL,那么拷贝7也指向NULL。

知道原13的random指向原7,那么拷贝13的random要指向拷贝7,即指向原7的next。

参考代码:

    //给拷贝节点random指针分配指向。
    while(cur)
    {
        copynode=cur->next;
        if(cur->random==NULL)
        {
            copynode->random=NULL;
        }
        else
        {
            copynode->random=cur->random->next;
        }
        cur=cur->next->next;
    }

解开原链表和拷贝链表:

我们用头插拷贝链表的方式将拷贝链表头插至另一链表。

参考代码:

 cur=head;
    Node* newhead=NULL;
    Node* newtail=NULL;
    while(cur)
    {
        copynode=cur->next;
        if(newhead==NULL)
        {
            newhead=newtail=copynode;
        }
        else
        {
            newtail->next=copynode;
            newtail=copynode;
        }
        cur->next=copynode->next;
        cur=copynode->next;
    }

完整代码参考:

typedef struct Node Node;
struct Node* copyRandomList(struct Node* head) 
{
    Node* cur=head;
    //在原节点后拷贝节点并连接起来。
    while(cur)
    {
        Node* newnode=(Node*)malloc(sizeof(Node));
        newnode->val=cur->val;
        newnode->next=cur->next;
        cur->next=newnode;
        cur=newnode->next;
    }
    cur=head;
    Node* copynode=NULL;
    //给拷贝节点random指针分配指向。
    while(cur)
    {
        copynode=cur->next;
        if(cur->random==NULL)
        {
            copynode->random=NULL;
        }
        else
        {
            copynode->random=cur->random->next;
        }
        cur=cur->next->next;
    }
    //断开连接
    cur=head;
    Node* newhead=NULL;
    Node* newtail=NULL;
    while(cur)
    {
        copynode=cur->next;
        if(newhead==NULL)


![img](https://img-blog.csdnimg.cn/img_convert/bc9a319472a6c972cc790c3737f5c890.png)
![img](https://img-blog.csdnimg.cn/img_convert/bf0cd93163f654c9d510473ef8964af7.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

x-1715847368974)]
[外链图片转存中...(img-aAH8XYsD-1715847368974)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值