wuyijia

导航

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

一.链表基础

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:记得之后再看递归从后向前

posted on 2023-05-12 19:58  小吴要努力  阅读(15)  评论(0编辑  收藏  举报