首页 > 其他分享 >day3-linked list-part01-7.5

day3-linked list-part01-7.5

时间:2024-07-09 15:26:30浏览次数:15  
标签:node ListNode val temp part01 self list next 7.5

tasks for today

1. 链表理论基础

2. 203.移除链表元素

3. 707.设计链表

4. 206.反转链表

------------------------------------------------

1. 链表理论基础

单链表:(singly-linked list)

链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。

链表的入口节点称为链表的头结点也就是head。

单链表中的指针域只能指向节点的下一个节点。

双链表:

双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。

双链表 既可以向前查询也可以向后查询。

循环链表:

顾名思义,就是链表首尾相连。

注意:数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

It is important to learn how to define linked list by yourself, even if it is usually defined in advance when doing coding practice on leetcode. Below are linked list's definition in python, go, rust

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

 // Definition for singly-linked list.
  type ListNode struct {
      Val int
      Next *ListNode
  }
//Definition for singly-linked list.
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ListNode {
  pub val: i32,
  pub next: Option<Box<ListNode>>
}

impl ListNode {
  #[inline]
  fn new(val: i32) -> Self {
    ListNode {
      next: None,
      val
    }
  }
}

the next usually store the next listnode, or none for the last node

related operation on linked list:

delete a listnode

add a listnode

2. 203.移除链表元素

here, if the head node should be deleted, to simlify the operation, a dummy node is used ahead of the head node. Or there should be a separate specific code snippet used for dealing with the condition where the head node should be deleted.

with dummy node VS without dummy node

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

        temp = dummy_node
        while temp.next:
            if temp.next.val == val:
                temp.next = temp.next.next
            else:
                temp = temp.next

        return dummy_node.next
class Solution:
    def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
        # here we don't use dummy head and introduce one only temp to record current listNode
        while head and head.val == val:
            head = head.next

        temp = head
        while temp and temp.next:
            if temp.next.val == val:
                temp.next = temp.next.next
            else:
                temp = temp.next
        
        return head

pay attention to how to initial a type instance in Go;

besides, it is not valid directly use "for temp.Next {}" in Go, the condition should be "temp.Next != nil"

func removeElements(head *ListNode, val int) *ListNode {
    dummy_node := &ListNode{}
    dummy_node.Next = head

    temp := dummy_node
    for temp.Next != nil {
        if temp.Next.Val == val {
            temp.Next = temp.Next.Next
        } else {
            temp = temp.Next
        }
    }
    return dummy_node.Next
}

Rust is disgusting!!!!!

impl Solution {
    pub fn remove_elements(head: Option<Box<ListNode>>, val: i32) -> Option<Box<ListNode>> {
        let mut dummy_node = Box::new(ListNode::new(0));
        dummy_node.next = head;

        let mut temp = dummy_node.as_mut();
        while let Some(nxt) = temp.next.take() {
            if nxt.val == val {
                temp.next = nxt.next;
            } else {
                temp.next = Some(nxt);
                temp = temp.next.as_mut().unwrap();
            }
        }
        return dummy_node.next
    }
}

3. 707.设计链表

here, a dummy node shows its advantage again. Besides, because it is as easy as array to get the length, so a variable recording the size is necessary.

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

class MyLinkedList:

    def __init__(self):
        self.dummy_node = ListNode()
        self.size = 0

    def get(self, index: int) -> int:
        if index < 0 or index >= self.size:
            return -1
        temp = self.dummy_node
        cur_ind = 0
        while cur_ind <= index:
            temp = temp.next
            cur_ind += 1
        return temp.val

    def addAtHead(self, val: int) -> None:
        self.dummy_node.next = ListNode(val=val, next=self.dummy_node.next)
        self.size += 1

    def addAtTail(self, val: int) -> None:
        temp = self.dummy_node
        while temp.next:
            temp = temp.next
        temp.next = ListNode(val=val, next=None)
        self.size += 1

    def addAtIndex(self, index: int, val: int) -> None:
        if index > self.size:
            return
        cur_ind = 0
        temp = self.dummy_node
        while cur_ind < index:
            temp = temp.next
            cur_ind += 1
        temp.next = ListNode(val=val, next=temp.next)
        self.size += 1

    def deleteAtIndex(self, index: int) -> None:
        if index < 0 or index >= self.size:
            return
        cur_ind = 0
        temp = self.dummy_node
        while cur_ind < index:
            temp = temp.next
            cur_ind += 1
        temp.next = temp.next.next
        self.size -= 1

4. 206.反转链表

- 双指针法

here, the initial definition of pre should be paid attention, pre=None is ok, do not define it as pre=ListNode(), or the last node will be a node with val=0

Note: The loop end when cur is None.

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        pre = None
        cur = head
        if not cur:
            return head
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

- 递归backtracking

in backtracking, the function's repetitive usage acturally realize "cur = temp" and "pre = cur" in the loop.

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        return self.reserve_step(None, head)

    def reserve_step(self, pre, cur):
        if cur == None:
            return pre
        temp = cur.next
        cur.next = pre

        return self.reserve_step(cur, temp)

标签:node,ListNode,val,temp,part01,self,list,next,7.5
From: https://blog.csdn.net/bbrruunnoo/article/details/140198673

相关文章

  • day4-linked list-part02-7.6
    taskfortoday1.24.两两交换链表中的节点2.19.删除链表的倒数第N个节点3.面试题02.07.链表相交4.142.环形链表II-------------------------------------------------------------------1.24.两两交换链表中的节点Inthispractice,payattentionto......
  • DataTable 与 泛型集合List<T>相互转换
    List转DataTablepublicstaticDataTableToDataTable<T>(thisList<T>list){DataTableresult=newDataTable();List<PropertyInfo>pList=newList<PropertyInfo>();Typetype=typeof(T);Array......
  • TNS问题排查 The listener supports no services
     检查tns的日志信息查看具体报错详情/u01/app/oracle/diag/tnslsnr/<hostname>/listener/alert/log.xml 修改litener.ora #listener.oraNetworkConfigurationFile:/u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora#GeneratedbyOracleco......
  • 【数据结构】—— 单链表(single linked list)
    文章目录1、单链表的定义优点和缺点单链表的构成2、单链表的创建初始化:3、单链表的接口实现打印尾插头插尾删头删查找在指定位置之前插入在指定位置之后插入删除指定位置的节点删除指定位置之后的节点销毁链表4、源代码1、单链表的定义单链表(SinglyLinkedList......
  • List 转 Page
    packagecom.leo.boot.jpa.stream;importorg.apache.commons.collections4.CollectionUtils;importorg.apache.commons.collections4.IterableUtils;importorg.springframework.beans.BeanUtils;importorg.springframework.data.domain.Page;importorg.springfram......
  • List 按照指定大小分片的几种方式
    如果有一个list<string>里面可能有1000份或者更多数据,如果需要进行入库等操作,需要拆分成指定大小每份进行处理,这种需求很常见,那么应该怎么做呢?首先我们需要将List<String> 转为多份后进行逐个处理, 处理批量事务注意事务哦 那么怎么将list转为多份呢? 下面介绍2......
  • 算法入门(6) 7.5
    小鱼的航程(改进版)题目背景题目描述有一只小鱼,它平日每天游泳$250$公里,周末休息(实行双休日),假设从周$x$开始算起,过了$n$天以后,小鱼一共累计游泳了多少公里呢?输入格式输入两个正整数$x,n$,表示从周$x$算起,经过$n$天。输出格式输出一个整数,表示小鱼累计游泳了多少公......
  • python数据容器(一)列表list
    思维导图代码1.数据容器入门2.数据容器:list(列表)name_list=['itheima','itcast','python']print(name_list)print(type(name_list))运行结果: name_list=['itheima',666,True]print(name_list)print(type(name_list))运行结果: name_l......
  • python: list
     #去重A=['geovindu','刘杰','江山','河水','刘杰','geovindu','张三','李五']B=[]foriinA:ifinotinB:B.append(i)print(B)C=set(A)......
  • HashTable,ArrayList,queue等常用方法
    HashTable,ArrayList,queue等常用方法HashMap是Java中非常常用的集合类,它存储键值对,并提供了一系列方便的方法来操作这些数据。以下是一些HashMap的常用方法:1.添加和获取元素:put(key,value):将指定的键值对添加到HashMap中。如果键已存在,则更新对应的值。get(ke......