首页 > 编程语言 >代码随想录算法训练营第三天|203.移除链表元素 、707.设计链表 、206.反转链表

代码随想录算法训练营第三天|203.移除链表元素 、707.设计链表 、206.反转链表

时间:2023-05-12 20:13:33浏览次数:54  
标签:index head cur val self 随想录 next 链表 移除

一.链表基础

1.最后一个节点的指针域指向null(空指针的意思)。

2.链表在内存中不是连续分布的。

3.链表的长度可以是不固定的,并且可以动态增删, 适合数据量不固定,频繁增删,较少查询的场景。

1 #链表节点的定义
2 class ListNode:
3     def __init__(self, val, next = None):
4          self.val = val
5          self.next = next

 java中对象每个对象都指向一个地址,所以递归使用Node类型

 1 public class ListNode {
 2     // 结点的值
 3     int val;
 4 
 5     // 下一个结点
 6     ListNode next;
 7 
 8     // 节点的构造函数(无参)
 9     public ListNode() {
10     }
11 
12     // 节点的构造函数(有一个参数)
13     public ListNode(int val) {
14         this.val = val;
15     }
16 
17     // 节点的构造函数(有两个参数)
18     public ListNode(int val, ListNode next) {
19         this.val = val;
20         this.next = next;
21     }
22 }

 

203. 移除链表元素

【注意】

 1.有两种方式:

  • 直接使用原来的链表来进行删除操作。
  • 设置一个虚拟头结点在进行删除操作——>统一了链表的操作。

 2.移除头结点和移除其他结点的操作是不一样的(因为头结点没有前一个结点)。——>将头结点后移动一位

3.移除头结点是一个持续的过程,所以应该用while循环,而不是用if判断; 进行查找删除的时候要注意是否为null(避免空指针异常)。

4.甚至虚拟头结点的时候:注意返回的是dummyNode->next ,而不是head。

【代码】

#在python中判断是否为空用的是:!= None 而不是: !=null

方式一:

 1 class Solution(object):
 2     def removeElements(self, head, val):
 3         """
 4         :type head: ListNode
 5         :type val: int
 6         :rtype: ListNode
 7         """
 8          # 不添加虚拟节点and pre Node方式
 9          # 时间复杂度 O(n)
10          # 空间复杂度 O(1)
11 
12         while(head and head.val == val): #不是用if  
13               head = head.next
14 
15         curr = head  #如果要删除头结点的下一个结点,就需要从head开始,指向next.next
16         
17         while(curr): #万一head为空,就直接返回
18             while(curr.next and curr.next.val == val): #遍历删除
19                 curr.next = curr.next.next
20             curr = curr.next
21         
22         return head

方式二:

 1 # Definition for singly-linked list.
 2 # class ListNode(object):
 3 #     def __init__(self, val=0, next=None):
 4 #         self.val = val
 5 #         self.next = next
 6 class Solution(object):
 7     def removeElements(self, head, val):
 8         """
 9         :type head: ListNode
10         :type val: int
11         :rtype: ListNode
12         """
13 
14         dummy_head = ListNode(next = head) #虚拟头结点
15         curr = dummy_head  #如果要删除头结点的下一个结点,就需要从head开始,指向next.next
16         
17         while(curr.next != None): #万一head为空,就直接返回
18             if(curr.next.val == val): #遍历删除
19                 curr.next = curr.next.next
20             
21             else:
22                 curr = curr.next
23         
24         return dummy_head.next #万一head被删除了

707. 设计链表

【注意】

1.遍历列表的时候为什么要定义一个指针?而不是直接操作头指针?

  因为我们操作完列表之后,要返回头结点

2.插入结点的时候要注意插入顺序。

3.删除第n个结点的时候,注意是要使n=cur.next

  1 class Node(object):
  2     def __init__(self, val = 0):
  3         self.val = val
  4         self.next = None
  5 
  6 class MyLinkedList(object):
  7 
  8     def __init__(self):
  9         self.head = Node() #虚拟头结点
 10         self.size = 0 #记录链表的大小
 11 
 12 
 13     def get(self, index):
 14         """
 15         :type index: int
 16         :rtype: int
 17         """
 18         if index < 0 or index >= self.size:
 19             return -1
 20         
 21         cur = self.head.next
 22         while(index):
 23             cur = cur.next
 24             index -= 1
 25         #for i in range(index)
 26         #   cur = cur.next
 27         return cur.val
 28 
 29 
 30     def addAtHead(self, val):
 31         """
 32         :type val: int
 33         :rtype: None
 34         """
 35         new_node = Node(val)
 36         new_node.next = self.head.next
 37         self.head.next = new_node
 38         #self.head.next = Node(val,self.head.next)
 39         self.size += 1
 40 
 41 
 42 
 43     def addAtTail(self, val):
 44         """
 45         :type val: int
 46         :rtype: None
 47         """
 48         new_node = Node(val)
 49         cur = self.head #虚拟头结点
 50         while(cur.next):
 51             cur = cur.next
 52         cur.next = new_node
 53         self.size += 1
 54 
 55     def addAtIndex(self, index, val):
 56         """
 57         :type index: int
 58         :type val: int
 59         :rtype: None
 60         """
 61         if index < 0 : 
 62             self.addAtHead(val)
 63             return
 64         elif index == self.size:
 65             self.addAtTail(val)
 66             return
 67         elif index > self.size:
 68             return
 69 
 70         node_new = Node(val)
 71         pre = self.head
 72         while(index):
 73             pre = pre.next #位置0号元素,列表中的第一元素
 74             index -= 1
 75         node_new.next = pre.next
 76         pre.next = node_new
 77         self.size += 1
 78 
 79 
 80     def deleteAtIndex(self, index):
 81         """
 82         :type index: int
 83         :rtype: None
 84         """
 85         if index < 0 or index >= self.size:
 86             return
 87         
 88         pre = self.head
 89         while(index):
 90             pre = pre.next #从虚拟头结点开始
 91             index -= 1
 92         pre.next = pre.next.next
 93         self.size -= 1
 94 
 95 
 96 
 97 # Your MyLinkedList object will be instantiated and called as such:
 98 # obj = MyLinkedList()
 99 # param_1 = obj.get(index)
100 # obj.addAtHead(val)
101 # obj.addAtTail(val)
102 # obj.addAtIndex(index,val)
103 # obj.deleteAtIndex(index)

ps:记得之后再看双链表的代码实现

206. 反转链表

【注意】

1.要把 cur->next 节点用tmp指针保存一下。

方式一:迭代法(双指针)

 1 # Definition for singly-linked list.
 2 # class ListNode(object):
 3 #     def __init__(self, val=0, next=None):
 4 #         self.val = val
 5 #         self.next = next
 6 class Solution(object):
 7     def reverseList(self, head):
 8         """
 9         :type head: ListNode
10         :rtype: ListNode
11         """
12         cur = head
13         pre = None
14         while(cur != None):
15             temp = cur.next
16             cur.next = pre #反转
17             pre = cur
18             cur = temp
19         return pre

方式二:递归

 1 # Definition for singly-linked list.
 2 # class ListNode(object):
 3 #     def __init__(self, val=0, next=None):
 4 #         self.val = val
 5 #         self.next = next
 6 class Solution(object):
 7     def reverseList(self, head):
 8         """
 9         :type head: ListNode
10         :rtype: ListNode
11         """
12         def reverse(pre,cur):
13             #递归结束条件cur = None
14             if not cur:
15                 return pre
16             temp = cur.next
17             cur.next = pre #反转
18 
19             return reverse(cur, temp)
20         #cur = head
21         #pre = None
22         #while(cur != None):
23             temp = cur.next
24             cur.next = pre #反转
25             #pre = cur
26             #cur = temp
27         return reverse(None, head)

ps:记得之后再看递归从后向前

标签:index,head,cur,val,self,随想录,next,链表,移除
From: https://www.cnblogs.com/wuyijia/p/17393847.html

相关文章

  • 四种语言刷算法之排序链表
    力扣148. 排序链表1、C/***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode*next;*};*/structListNode*sortList(structListNode*head){intn=0;structListNode*newHead=(structListNode*)m......
  • 移除链表元素
     /** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode() : val(0), next(nullptr) {} *     ListNode(int x) : val(x), next(nullptr) {} *     ......
  • 数据链表的概念
    数据链表(DataLinkedList)是一种常见的数据结构,用于存储和操作一系列元素的集合。它由一系列节点(Node)组成,每个节点包含数据元素和一个指向下一个节点的引用(指针)。数据链表与数组相比具有以下特点:1.动态性:数据链表的长度可以根据需要进行动态调整,可以方便地进行插入和删除操作,而......
  • 4、在链表中穿针引线
    1、反转链表206-反转链表/***非递归实现*最终状态如下*cur、next->null*prev->newHead*/publicstaticListNodereverseList1(ListNodehead){ListNodeprev=null;ListNodecur=head;ListNodenext;while(cur!=null){......
  • 2023-05-10:给你一棵以 root 为根的二叉树和一个 head 为第一个节点的链表 如果在二叉
    2023-05-10:给你一棵以root为根的二叉树和一个head为第一个节点的链表如果在二叉树中,存在一条一直向下的路径且每个点的数值恰好一一对应以head为首的链表中每个节点的值,那么请你返回True否则返回False。一直向下的路径的意思是:从树中某个节点开始,一直连续向下的路径......
  • 回文链表
    /方法一:反转链表逐个比较/***Definitionforsingly-linkedlist.*structListNode{*intval;*ListNode*next;*ListNode(intx):val(x),next(NULL){}*};*///classSolution{//public://boolisPalindrome(ListNode*head){//ListNo......
  • 单链表——追加函数(有无懂的大佬解答一下why不加强制类型过不去)
    #include<bits/stdc++.h>usingnamespacestd;typedefstruct{intid;stringname;}Data;typedefstruct{ DatanodeData; structNode*nextNode;}CLtype;//追加链表CLtype*CLAddEnd(CLtype*head,Datanodedata){CLtype*node,*htemp; if(!(node=(CLt......
  • 双链表和队列-->gcc编译
    双链表队列doublueList.h#include<stdlib.h>#include<stdio.h>#include<assert.h>#include<stdbool.h>typedefintLTDataType;typedefstructDList{ LTDataTypedata; structDList*next; structDList*prev;}LTNode;LTNode*init();......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。第一章 数组part01
    今天开始第一天,其实之前也刷过题,也写过博客,可是没有坚持下去;主要是没有动力吧,我又是一个严重的拖延症患者,还好遇到刷到Carl哥的视频,记得是在bilibili分享的二分法视频,感觉讲的挺好的,就加了微信;然后发现有刷题训练营,太适合我这种人了,果断加入,哈哈,废话不多说,开始刷题。  第......
  • 代码随想录算法训练营第七天 | 454.四数相加II 、383.赎金信 
    ......