代码随想录训练营第三天 || 区间和 移除链表元素

区间和:

思路:

1.利用前缀和:把数组中下标对应的(假设下标为n)前n项和提前算出来(比如前0项的和,前1项的和),等求区间和时只需要,把对应数组下标的和相减,就可求出区间和。例如求前2到5的和,只需要用先前求过的前5项和-前1项和,就是2到5的和。这样的好处是如果要求的区间和,重复次数多时,相较于,纯暴力求解会简单很多

2.暴力:每给出一个区间,就把区间内的每一项用循环加起来

第一想法:

因为做过一遍,所以一开始就想到了前缀和的思路

看完代码随想录之后:

不同于给出的答案,自己用另一种方式也实现了案例,但也是用的前缀和。

代码:

前缀和:

import sys
#print("数组长度")
a = int(input())
vec=[0]*a
#print("请输入数组元素")
for i in range(a):
    vec[i]=int(input())
num=0
p=[0]*a
for i in range(a):
    num+=vec[i]
    p[i]=num
#print("请输入区间")
input = sys.stdin.read#
b=input().split()
ind=0
answer=[]
while ind<len(b):
    j=int(b[ind+1])
    k=int(b[ind])
    if k == 0:
        answer.append(p[j])
    else:
        answer.append(p[j]-p[k-1])
    ind+=2
for i in answer:
    print(f"{i}")

遇到的问题:

1.python如何多行输入:引入 sys库函数中的标准输入,对input重新定义,让input接受输入的所有数据,直到遇到EOF结束标志

移除链表元素:

思路:

查找指定结点并移除,注意需要查找要移除的结点的前一个结点,让要移除结点前一结点的下一个,指向要移除结点的后一个结点

代码:

class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        dummy_head = ListNode(next=head)

        current_head = dummy_head
        while current_head.next !=None:
            if current_head.next.val ==val:
                current_head.next=current_head.next.next
            else:
                current_head=current_head.next#
        return dummy_head.next

遇到的问题:

1.对于dumm_head(虚拟头节点),next作为返回值:开始使用current修改链表,并且current最后指向链表的最后,但返回值要是链表的头节点,所以返回dummy_head.next(头节点)

设计链表:

思路:

1.获取指定下标的链表:先判断下标的有效性,使用虚拟头节点,查找即可

2.头插入:通过虚拟头节点插入

3.尾插入:通过查找链表的尾结点,进行插入

4.在指定下标的前插入:查找指定下标的前一个下标的结点,然后在后面插入

5,删除结点:查找指定删除下标的前一个下标的结点,然后删除后面的结点,来间接实现

代码:

class ListNode:
    def __init__(self,val = 0,next=None):
        self.val = val
        self.next=next
class MyLinkedList:
    
    def __init__(self):
        self.dummy_head = ListNode()
        self.size = 0

    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:#可能会越界
            return -1
        current_head=self.dummy_head.next
        for a in range(index):
            current_head=current_head.next
        return current_head.val
            

    def addAtHead(self, val: int) -> None:
        NewNode=ListNode()
        NewNode.val = val
        NewNode.next =self.dummy_head.next
        self.dummy_head.next=NewNode
        self.size+=1#调用类中的变量,加self

    def addAtTail(self, val: int) -> None:
        NewNode=ListNode()
        NewNode.val = val
        current_head=self.dummy_head#去掉next
        while current_head.next :
            current_head=current_head.next
        current_head.next = NewNode
        self.size+=1

    def addAtIndex(self, index: int, val: int) -> None:
        
        if index>self.size:
            return 
        else:
            NewNode=ListNode()
            NewNode.val = val
            current_head=self.dummy_head
            for a in range(index):
                current_head=current_head.next
            NewNode.next=current_head.next
            current_head.next=NewNode
            self.size+=1

    def deleteAtIndex(self, index: int) -> None:
        if index<0 or index>=self.size:
            return
        else:
            current_head=self.dummy_head
            for a in range(index):
                current_head=current_head.next
            current_head.next=current_head.next.next
            self.size-=1

遇到的问题:

1.python的对象问题

2.对于无效下标的判断不够全面

反转链表:

思路:

两个变量,一个变量记录反转前结点前的结点,一个变量记录反转前结点后的结点,这样可以实现交换,并且通过记录变量反转前的结点,可以使链表继续按照原来顺序遍历

代码:

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        cur=head
        pre=None
        while cur:
            temp=cur.next#保存一个临时变量的目的是,更改后,还可以按照原来的 顺序进行遍历链表
            cur.next=pre
            pre=cur
            cur=temp
        return pre

遇到的问题:

1.对于链表反转某个结点后仍然可以继续遍历:通过一个临时变量记录原本的后一结点

2.pre的作用,记录前一个结点

今日总结:

感觉非常充实,挺烧脑的,希望自己能坚持下来,加油

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值