Table of contents
141. Ring Linked List (easy)
topic
Given a linked list, determine whether there is a cycle in the linked list.
If there is a node in the linked list that can be reached again by continuously tracking the next pointer, then there is a cycle in the linked list. To represent a cycle in a given list, we use the integer pos to denote the position in the list where the tail of the list joins (indexes start at 0). If pos is -1, there are no cycles in the list. Note: pos is not passed as a parameter, it is just to identify the actual situation of the linked list.
Returns true if there is a cycle in the linked list. Otherwise, returns false.
Source: LeetCode
Link: https://leetcode-cn.com/problems/linked-list-cycle
The copyright belongs to LeetCode. For commercial reprints, please contact the official authorization, for non-commercial reprints, please indicate the source.
V1 (fast and slow pointer)
Using the fast and slow pointers, the slow pointer moves backward one position at a time, and the fast pointer moves backward two positions at a time. If there is a ring, there must be a time when the fast and slow pointers are equal.
The space complexity of the algorithm in this case is O(1), using only the extra space of two pointers. The time complexity is O(N), where N is the number of nodes in the linked list.
class Solution:
def hasCycle(self, head: ListNode) -> bool:
if not head or not head.next:
return False
slow, fast = head, head.next
while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
Result:
What went wrong:
- Originally, the judgment conditions in lines 3 and 4 were not added, and an error was reported:
Notice:not head
andnot head.next
Both judgment conditions are required, the former is to prevent the occurrence of an empty linked list, and the latter is to prevent the occurrence of a linked list with only one element and no ring under the premise of a non-empty linked list. - The original judgment condition in line 7 is if not fast, and the latter judgment condition is missing, and an error is reported:
Code when written and tested locally:
# 定义结点
class Node(object):
def __init__(self, item):
self.item = item
self.next = None
# 定义单链表
class SingleLinkList(object):
def __init__(self):
self._head = None # 首地址指针head
def hasCycle(head):
if not head or not head.next:
return False
slow, fast = head, head.next
while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
link_list = SingleLinkList()
node1 = Node(3)
node2 = Node(2)
node3 = Node(0)
node4 = Node(-4)
link_list._head = node1
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node2
print(hasCycle(node1))
V2 (hash table)
Put all the seen elements into the seen collection, and judge whether the next element appears in the seen.
def hasCycle(head):
seen = set()
while head:
if head not in :
seen.add(headseen)
head = head.next
else:
return True
return False
result:
- Time complexity: O(N), where N is the number of nodes in the linked list. In the worst case we need to traverse each node once.
- Space complexity: O(N), where N is the number of nodes in the linked list. Mainly the overhead of the hash table, in the worst case we need to insert each node into the hash table once.
283. Moving Zero (easy)
topic
Given an array nums, write a function to move all 0s to the end of the array while maintaining the relative order of the nonzero elements.
V1
Two pointers i, j, i is used to find 0, j is used to find the first non-zero element after i, and then exchange positions.
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i = 0
while i < len(nums) - 1:
if nums[i] == 0:
break
i += 1
if i == len(nums) - 1:
return nums
while i < len(nums) - 1:
j = i + 1
while j < len(nums):
if nums[j] != 0:
break
j += 1
if j == len(nums):
break
nums[i], nums[j] = nums[j], nums[i]
i += 1
while nums[i] != 0:
i += 1
return nums
Result:
It can be seen that it is very time consuming.
v2
There are also two pointers, one pointing down from the beginning to ensure that the pointed positions are all non-zero, and the other is used to find all non-zero items.
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
i = j = 0
while j < len(nums):
if nums[j] != 0:
nums[i], nums[j] = nums[j], nums[i]
i += 1
j += 1
result:
27. Remove elements (easy)
topic
Given an array nums and a value val, you need to remove all elements whose value is equal to val in place, and return the new length of the removed array.
Don't use extra array space, you have to use only O(1) extra space and modify the input array in-place.
The order of elements can be changed. You don't need to consider elements in the array beyond the new length.
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-element
Copyright belongs to LeetCode Network. For commercial reprints, please contact the official authorization, for non-commercial reprints, please indicate the source.
V1
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i = 0
while i < len(nums):
if nums[i] == val:
del nums[i]
else:
i += 1
return len(nums)
result:
v2
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
index = 0
for i in nums:
if i != val:
nums[index] = i
index += 1
return index
result:
V3
double pointer.
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, j = 0, len(nums) # 注意j的初始值
while i < j:
if nums[i] == val:
nums[i] = nums[j-1]
j -= 1
else:
i += 1
return i
result:
26. Remove duplicates in sorted array (easy)
topic
Given an ordered array nums, please delete repeated elements in place so that each element appears only once, and return the new length of the deleted array.
Don't use extra array space, you have to modify the input array in-place and do so using O(1) extra space.
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
The copyright belongs to Leetcode Network. For commercial reprints, please contact the official authorization, for non-commercial reprints, please indicate the source.
V1
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if len(nums) <= 1:
return len(nums)
i, index = 1, 1
while i < len(nums):
if nums[i] not in nums[:index]:
nums[index] = nums[i]
index += 1
i += 1
return index
result:
v2
After reading other people's answers, I found out that I missed a key information when I read the question:ordered array。
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
if not nums:
return 0
i, j = 0, 0
while j < len(nums):
if nums[i] != nums[j]:
i += 1
nums[i] = nums[j]
j += 1
return i + 1
result:
80. Remove Duplicates in Sorted Array II(medium)
topic
Given an ordered array nums, please delete repeated elements in place, so that each element appears at most twice, and return the new length of the deleted array.
Don't use extra array space, you have to modify the input array in-place and do so using O(1) extra space.
Source: LeetCode
Link: https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii
The copyright belongs to Leetcode.com. For commercial reprints, please contact the official authorization, for non-commercial reprints, please indicate the source.
V1
I failed to write it myself, and it is in the reference solution.
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
i = 2
for j in nums[2:]:
if nums[i-2] != j:
nums[i] = j
i += 1
return i
Result:
At the beginning, I always thought about counting the number of occurrences of the value pointed by the pointer, but I didn't expect to compare it directly with the previous two values.