跟着《代码随想录》练习代码

更新中。。。学习过程中的记录,有错误请指正。

数组

二分查找704

class Solution:
    def search(self,nums:list,target:int)->int:
        left = 0
        right = len(nums)-1
        while left<=right:
            mid = (left+right)//2
            guess = nums[mid]
            if guess == target:
                return mid
                break
            elif guess > target:
                right = mid -1
            else:
                left = mid + 1
        return -1


nums = [int(c) for c in input().split(" ")]#⭐
target = int(input())
solu = Solution()
out = solu.search(nums,target)
print(out)

相关题目推荐
35.搜索插入位置
和二分法的区别就是一个返回-1,一个返回left。

class Solution:
    def searchInsert(self,nums:List[int],target:int) -> int:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right)//2
            if nums[mid] == target:
                return mid
            elif nums[mid] > target:
                right = mid -1
            else:
                left = mid + 1
        return left

34.在排序数组中查找元素的第一个和最后一个位置

class Solution:
    def searchRange(self,nums:List[int],target:int)-> List[int]:
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                start = mid
                end = mid
                while nums[start] == target and start > 0 and nums[start - 1] == target :
                    start = start -1
                while nums[end] == target and end < len(nums) - 1 and nums[end + 1] == target:
                    end = end + 1
                return [start,end]
            elif nums[mid] > target:
                right = mid - 1
            else:
                left = mid + 1
        return [-1,-1]

nums = [int(c) for c in input().split(" ")]
target = int(input())
solu = Solution()
out = solu.searchRange(nums,target)
print(out)

69.x 的平方根

class Solution:
    def mySqrt(self, x : int ) -> int:
        if x == 0:
            return 0
        left = 1
        right = x
        while left <= right:
            mid = (left + right)//2
            if mid**2 == x :
                return int(mid)
            elif mid**2 > x:
                right = mid
            else:
                if (mid + 1) ** 2 > x:
                    return math.floor(mid)
                else:
                    left = mid

367.有效的完全平方数

class Solution:
    def minSubArrayLen(self,target:int,nums:List[int])->int:
        left = 0
        right = 0
        length = len(nums)
        min_len = length+1
        cur_sum = 0

        for i in range(length):
        # while right < length:
            cur_sum = cur_sum + nums[right]
            while cur_sum >= target:
                min_len = min(right - left + 1 , min_len)
                cur_sum -= nums[left]
                left = left + 1
            right = right + 1
        return min_len if min_len != length+1 else 0

移除元素27

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        length = len(nums)
        new_len = length

        for i in range(new_len):
            if nums[i] == val:
                new_len = new_len -1
                for j in range(i, new_len):
                    nums[j]= nums[j+1]
                nums[-1] = 101
                print(nums)##
        return new_len,nums[:new_len]
nums = [int(c) for c in input().split(" ")]
val = int(input())
solu = Solution()
out = solu.removeElement(nums,val)
print(out)

输入为:

[0,1,2,2,3,0,4,2]
2

时,会出现错误
在这里插入图片描述
双指针法

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        length = len(nums)
        left = 0
        for right in range(length):
            if nums[right] != val:
                nums[left] = nums[right]
                left = left+1
        return left

相关题目推荐

  • 26.删除排序数组中的重复项
class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        left = 0
        right = 1
        for i in range(len(nums)-1):

            if nums[left] != nums[right]:
                left = left + 1
                nums[left] = nums[right]
            right = right + 1

        return left+1

num = [int(c) for c in input().split(" ")]
solu = Solution()
out = solu.removeDuplicates(num)
print(out)
  • 283.移动零
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        left = 0
        right = 0
        for i in range(len(nums)):
            if nums[right] != 0:
                nums[left] = nums[right]
                left = left + 1
            right = right + 1
        for j in range(left,len(nums)):
            nums[j] = 0
        return nums

num = [int(c) for c in input().split(" ")]
solu = Solution()
out = solu.moveZeroes(num)
print(out)
  • 844.比较含退格的字符串
ss Solution:
    def backspaceCompare(self, S: str, T: str) -> bool:
        def build(s: str) -> str:
            ret = list()
            for ch in s:
                if ch != "#":
                    ret.append(ch)
                elif ret:
                    ret.pop()
            return "".join(ret)

        return build(S) == build(T)


s = input()
t = input()
solu = Solution()
out = solu.backspaceCompare(s,t)
print(out)

有序数组的平方977

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums)-1
        result = []
        while left <= right:
            if nums[left]**2 >= nums[right]**2:
                result.append(nums[left]**2)
                left = left + 1
            else:
                result.append(nums[right]**2)
                right = right - 1
        return result[::-1]

长度最小的子数组209

class Solution:
    def minSubArrayLen(self,target:int,nums:List[int])->int:
        left = 0
        right = 0
        length = len(nums)
        min_len = length+1
        cur_sum = 0

        for i in range(length):
        # while right < length:
            cur_sum = cur_sum + nums[right]
            while cur_sum >= target:
                min_len = min(right - left + 1 , min_len)
                cur_sum -= nums[left]
                left = left + 1
            right = right + 1
        return min_len if min_len != length+1 else 0

螺旋矩阵59

class Solution:
    def generateMatrix(self, n : int) -> List[List[int]]:
        index = 1
        mid = n //2
        rows = n
        cols = n
        nums = [[0] * cols for _ in range(rows)]
        for loop in range(n//2):
            for j in range(loop, n - loop - 1):
                nums[loop][j] = index
                index = index + 1
                # print(nums)
            for j in range(loop, n - loop - 1):
                nums[j][n - loop - 1] = index
                index = index + 1
            for j in range(n - loop - 1, loop,  -1):
                nums[n - loop -1][j] = index
                index = index + 1
            for j in range (n - loop - 1, loop,  -1):
                nums[j][loop] = index
                index = index + 1
        if n % 2 != 0 :
            nums[mid][mid] = n**2
        return nums

n = int(input())
solu = Solution()
out = solu.generateMatrix(n)
print(out)

for i in range(10, 0, -1):
    print(i)

这将输出:

10
9
8
7
6
5
4
3
2
1

链表

移除链表元素203

from typing import List,Optional
class ListNode:
    def __init__(self, val = 0, next = None ):
        self.val = val
        self.next = next

# class Solution:
#     def removeElements(self,head:Optional[ListNode],val:int)->Optional[ListNode]:
#         while head:
#             if head.val == val:
#                 head.next = head.next.next
#             else:
#                 head = head.next
#         return head
#这个代码的问题在于,当头节点(head)就等于要删除的值(val)时,并没有将头节点移动到下一个节点。->虚拟结点

class Solution:
    def removeElements(self,head:Optional[ListNode],val:int)->Optional[ListNode]:
        dummy_head = ListNode(next = head)
        current = dummy_head
        while current.next:
            if current.next.val == val:
                current.next = current.next.next
            else:
                current = current.next
        return dummy_head.next
head = ListNode(1)
node1 = ListNode(2)
node2 = ListNode(6)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
node6 = ListNode(6)
head.next = node1
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node6
solu = Solution()
val = 6
new_head = solu.removeElements(head, val)
current = new_head
result = []
while current:
    result.append(current.val)
    current = current.next

print(result) # 输出 [1, 2, 3, 4, 5]

设计链表707

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 = self.dummy_head.next
        for i in range(index):
            current = current.next
        return current.val

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


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

    def addAtIndex(self,index:int,val:int)->None:
        if index < 0 or index > self.size:
            return

        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next = ListNode(val, next=current.next)
        self.size += 1

    def deleteAtIndex(self,index: int)->None:
        if index < 0 or index >= self.size:
            return

        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next =current.next.next
        self.size -= 1

⭐有index的时候,注意index范围;添加或删除时要增减size。
初始化方式改变时,代码变为:

class MyLinkedList:
    def __init__(self):
        self.dummy_head = ListNode(0)
        self.size = 0

    def get(self,index:int)->int:
        if index < 0 or index >= self.size:
            return -1

        current = self.dummy_head
        for i in range(index+1):
            current = current.next
        return current.val

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


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

    def addAtIndex(self,index:int,val:int)->None:
        if index < 0 or index > self.size:
            return

        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next = ListNode(val, next=current.next)
        self.size += 1

    def deleteAtIndex(self,index: int)->None:
        if index < 0 or index >= self.size:
            return

        current = self.dummy_head
        for i in range(index):
            current = current.next
        current.next =current.next.next
        self.size -= 1

反转链表206

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        prev, curr = None,head
        while curr:
            next = curr.next#保存一下 cur的下一个节点,因为接下来要改变cur->next
            curr.next = prev # 对于新链表curr的下一个是prev
            prev = curr #更新prev指针
            curr = next #更新curr指针
        return prev

两两交换链表中的结点24

class Solution:
    def swapPairs(self,head:Optional[ListNode]) -> Optional[ListNode]:
        dummy_head = ListNode(next=head)
        cur = dummy_head
        while cur.next and cur.next.next:
            temp = cur.next
            temp1 = cur.next.next.next##
            cur.next = cur.next.next
            cur.next.next = temp
            temp.next = temp1##
            cur = cur.next.next##
        return dummy_head.next

删除链表的倒数第N个节点19

class Solution:
    def removeNthFromEnd(self,head:Optional[ListNode],n:int)->Optional[ListNode]:
        dummy_head = ListNode(next=head)
        fast = dummy_head
        slow = dummy_head
        for i in range(n):
            fast = fast.next
        while fast.next:
            fast = fast.next
            slow = slow.next
        slow.next = slow.next.next
        return dummy_head.next

链表相交160

class ListNode:
    def __init__(self,x):
         self.val = x
         self.next = None
class Solution:
    def getIntersectionNode(self,headA: ListNode, headB:ListNode) ->ListNode:
         A = headA
         B = headB
         while A != B:
              A = A.next if A else headB
              B = B.next if B else headA
          return A
A = A.next if A else headB
等价于
if A:
   A = A.next
else:
   A = headB

环形链表142

class Solution:
    def detectionCycle(self,head:ListNode)->ListNode:
        slow = head
        fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

            if slow == fast:
                slow = head
                while slow != fast:
                    slow = slow.next
                    fast = fast.next
                return slow
        return None

哈希表

有效的字母异位词242

class Solution:
    def isAnagram(self,s:str,t:str) ->bool:
        n = 26
        s_count = [0]*n
        t_count = [0]*n
        for i in s:
            s_count[ord(i) - ord("a")] += 1
        for i in t:
            t_count[ord(i) - ord("a")] += 1
        if s_count == t_count:
            return True
        else:
            return False

注意:

ord(i) - ord("a")

两个数组的交集349

class Solution:
    def intersection(self,nums1:List[int],nums2:List[int])->List[int]:
        nums1 = set(nums1)
        length2 = len(nums2)
        count = []
        for i in range(length2):
            if nums2[i] in nums1:
                count.append(nums2[i])
        count = set(count)
        count = list(count)
        return count   
class Solution:
    def intersection(self,nums1:List[int],nums2:List[int])->List[int]:
        n = 1001
        count1 = n*[0]
        count2 = n*[0]
        res = []
        for i in nums1:
            count1[i] += 1
        for i in nums2:
            count2[i] += 1
        for i in range(n):
            if count1[i]*count2[i] > 0:
                res.append(i)
        return res
class Solution:
    def intersection(self, nums1:List[int],nums2:List[int])->List[int]:
        table = {} #字典
        for num in nums1:
            table[num] = table.get(num, 0) + 1
            # 这行代码中,table.get(num, 0)的作用是从字典table中获取键为num的元素,如果该键不存在,则返回默认值0。
            # 因此,整个表达式的含义是,如果num在字典中存在,则将其对应的值加1;否则,将其对应的值设置为1。
        # 使用集合存储结果
        res = set()
        for num in nums2:
            if num in table:
                res.add(num)
                del table[num]
        return list(res)
class Solution:
    def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
        return list(set(nums1) & set(nums2))

快乐数202

class Solution:
    def isHappy(self,n:int)->bool:
        res = set()
        while n != 1:
            n = str(n)
            sum = 0
            for i in n:
                sum += int(i)**2
            if sum in res:
                return False
            else:
                res.add(sum)
                n = sum
        return True

两数之和1

什么时候使用哈希法,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。

class Solution:
    def twoSum (self,nums: List[int],target:int)->List[int]:
        hashtable = dict()
        length = len(nums)
        for i,num in enumerate(nums):
            if target - num in hashtable:
            # if target - num in set(nums[i+1:]):
                return [i, hashtable[target-num]]
            hashtable[nums[i]] = i  #在哈希表中以元素值为键,以对应下标为值进行存储。
        return []
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in range (len(nums)):
            for j in range (i+1, len(nums)):
                if nums[i]+nums[j]==target:
                        return [i,j]

赎金信383

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        ransom_count = [0] * 26
        magazine_count = [0] * 26
        for c in ransomNote:
            ransom_count[ord(c) - ord('a')] += 1
        for c in magazine:
            magazine_count[ord(c) - ord('a')] += 1
        return all(ransom_count[i] <= magazine_count[i] for i in range(26))
        #这是一个Python代码行,用于检查一个名为ransom_count的列表中的每个字母在另一个名为magazine_count的列表中是否都有足够的数量。这两个列表都包含26个元素,分别代表26个字母。如果有任何一个字母的数量在ransom_count中大于在magazine_count中的数量,那么这个条件将返回False,否则返回True。换句话说,这个代码行的作用是确保magazine_count中的每个字母都至少有ransom_count中相应字母的数量那么多。

四数相加454

class Solution:
    def fourSumCount(self, nums1:List[int],nums2:List[int],nums3:List[int],nums4:List[int])->List[int]:
        length1 = len(nums1)
        length2 = len(nums2)
        count = 0
        hashtable = {}
        for num3 in nums3:
            for num4 in nums4:
                hashtable[num3 + num4] = hashtable.get(num3 + num4, 0) + 1
        print(hashtable)

        for i in range(length1):
            for j in range(length2):
                if -nums1[i]-nums2[j] in hashtable.keys():
                    count += hashtable[-nums1[i]-nums2[j]]
        return count
solu = Solution()
nums1 = [int(c) for c in input().split(' ')]
nums2 = [int(c) for c in input().split(' ')]
nums3 = [int(c) for c in input().split(' ')]
nums4 = [int(c) for c in input().split(' ')]
out = solu.fourSumCount(nums1, nums2, nums3, nums4)
print(out)

赎金信383

法一:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        hashtable = {}
        for s in magazine:
            hashtable[s] = hashtable.get(s, 0) + 1
        for s in ransomNote:
            if s in hashtable.keys():
                if hashtable[s] == 0:
                    return False
                else:
                    hashtable[s] -= 1
            else:
                return False
        return True

法二:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        ransom_count = [0] * 26
        magazine_count = [0] * 26
        for c in ransomNote:
            ransom_count[ord(c) - ord('a')] += 1
        for c in magazine:
            magazine_count[ord(c) - ord('a')] += 1
        return all(ransom_count[i] <= magazine_count[i] for i in range(26))

三数之和15

class Solution:
    def threeSum(self, nums:List[int])->List[List[int]]:
        length = len(nums)
        # right = length - 1
        res = []
        nums.sort()
        for i in range(length - 2):
            # 如果第一个元素已经大于0,不需要进一步检查
            if nums[i] > 0:
                return res
            left = i + 1
            right = length - 1
            # 跳过相同元素以避免重复
            if i > 0 and nums[i] == nums[i-1]:
                continue

            while left < right:
                if nums[i] + nums[left] + nums[right] > 0:
                    right -= 1
                elif nums[i] + nums[left] + nums[right] < 0:
                    left += 1
                else:
                    res.append([nums[i], nums[left], nums[right]])
                    # 跳过相同的元素以避免重复
                    while right > left and nums[right] == nums[right - 1]:
                        right -= 1
                    while right > left and nums[left] == nums[left + 1]:
                        left += 1
                    right -= 1
                    left += 1
        return res

四数之和18

class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        res = []
        length = len(nums)
        nums.sort()
        for i in range(length):
            # 剪枝
            if nums[i] > target and target > 0:
                break
            # 去重
            if i > 0 and nums[i] == nums[i-1]:
                continue

            for j in range(i+1, length):
                if j > i+1 and nums[j] == nums[j - 1]:
                    continue
                left = j+1
                right = length - 1
                while left < right:
                    if nums[i] + nums[j] + nums[left] + nums[right] > target:
                        right -= 1
                    elif nums[i] + nums[j] + nums[left] + nums[right] < target:
                        left += 1
                    else:
                        res.append([nums[i], nums[j], nums[left], nums[right]])
                        while left < right and nums[left] == nums[left + 1]:
                            left += 1
                        while left < right and nums[right] == nums[right - 1]:
                            right -= 1
                        right -= 1
                        left += 1
        return res

字符串

反转字符串344

class Solution:
    def reverseString(self,s:List[str])->List[str]:
        length = len(s)
        for i in range(length//2):
            temp = s[i]
            s[i] = s[length-1-i]
            s[length-1-i] = temp
        return s
s = [c for c in input().split(' ')]
solu = Solution()
out = solu.reverseString(s)
print(s)

反转字符串II 541

class Solution:
    def reverseStr(self, s:str, k:int)->str:
        s = list(s)  # @1
        length = len(s)
        loop = length//(2*k)
        remain = length%(2*k)
        for i in range(loop):
            for j in range(k//2):
                temp = s[2*k*i + j]
                s[2*k*i + j] = s[2*k*i + k-1 -j]
                s[2 * k * i + k-1 - j] = temp
        if remain < k:
            for i in range(remain//2):
                temp = s[length-remain+i]
                s[length-remain+i] = s[length-1-i]
                s[length-1-i] = temp
        else:
            for i in range(k//2):
                temp = s[length-remain+i]
                s[length - remain + i] = s[length - remain + k -1 - i]
                s[length - remain + k -1 - i] = temp
        return ''.join(s)
s = input()
k = int(input())
solu = Solution()
out = solu.reverseStr(s,k)
print(out)

1、一开始@1行没有加,报错:

TypeError: 'str' object does not support item assignment

原因:这个错误是因为正在尝试更改一个字符串对象的某个字符,但是字符串是不可变的,也就是说,它们的值一旦被赋予就不能被修改。因此,如果尝试对字符串进行item assignment,Python会引发TypeError。

例如,以下代码将导致TypeError: ‘str’ object does not support item assignment:

Copy Codemy_string = "Hello"
my_string[0] = "J"  # trying to change the first character from "H" to "J"

为了避免这个错误,可以使用其他数据类型来存储和操作可变的数据,例如列表或字典。如果需要在字符串中进行修改,则可以创建一个新的字符串并使用字符串切片来复制原始字符串的内容,并使用新值替换需要更改的部分。

注意:在 Python 和 Java 等语言中,字符串都被设计成「不可变」的类型,即无法直接修改字符串的某一位字符,需要新建一个字符串实现。在 C++ 语言中, string 被设计成「可变」的类型,因此可以在不新建字符串的情况下实现原地修改。

2、str转list:

s = list(s)

list转str:

result = ''.join(s)

替换空格05

class Solution:
    def replaceSpace(self,s:str) -> str:
        res = []
        for i in s:
            if i == ' ':
                res.append("%20")
            else:
                res.append(i)
        return "".join(res)
class Solution:
    def replaceSpace(self,s:str) ->str:
        s = list(s)
        length = len(s)
        for i in range(length):
            if s[i] == ' ':
                s[i] = "%20"
        return ''.join(s)
s = input()
solu = Solution()
out = solu.replaceSpace(s)
print(out)

翻转字符串里的单词151

class Solution:
    def reverseWords(self, s: str)-> str:
        s = s.strip()
        # Python中的"s = s.strip()"代码会从字符串"s"的开头和结尾删除任何空白字符(包括空格、制表符和换行符),并返回一个新的字符串,原始字符串"s"不会被修改。
        # 反转整个字符串
        s = s[::-1]
        # 反转单词
        s = s.split()
        s = list(s)
        s = [word[::-1] for word in s]
        return ' '.join(s)

左旋转字符串58

class Solution:
    def reverseLeftWords(self,s:str,n:int)->str:
        s = list(s)

        for i in range(n):
            temp = s[0]
            for j in range(len(s)-1):
                s[j] = s[j+1]
            s[len(s)-1] = temp
        return "".join(s)

超时了。。。

#法二:切片
class Solution:
     def reverseLeftWords(self,s:str,n:int)->str:
         return s[n:]+s[:n]

# 法三:列表遍历拼接
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        res = []
        for i in range(n, len(s)):
            res.append(s[i])
        for i in range(n):
            res.append(s[i])
        return ''.join(res)

实现strStr()28

class Solution:
    def strStr(self, haystack: str, needle: str) ->int:
        length1 = len(needle)
        length2 = len(haystack)
        left = 0
        right = left + length1 -1
        for i in range(length2 - length1 + 1):
            if haystack[left+i: right + i + 1] == needle:
                return left + i
        return -1```
⭐**Python切片**
Python中的切片(slicing)是指从一个序列中取出一部分元素的操作。可以对列表、字符串、元组等序列类型进行切片操作。
切片操作使用方括号和冒号表示,语法如下:

```python
sequence[start:stop:step]

其中,sequence是要切片的序列,start表示切片的起始位置(包含),stop表示切片的结束位置(不包含),step表示切片的步长。如果省略start,则默认为0;如果省略stop,则默认序列长度;如果省略step。则默认为1。

>>> lst = [1, 2, 3, 4, 5]
>>> lst[1:3]  # 取出索引为 1 和 2 的元素
[2, 3]

>>> lst[:3]  # 省略 start,从头开始取出前 3 个元素
[1, 2, 3]

>>> lst[::2]  # 每隔一个元素取出一个
[1, 3, 5]

>>> s = 'hello, world!'
>>> s[7:]  # 从索引为 7 的位置开始取出到结尾的所有字符
'world!'

>>> s[:5]  # 取出前 5 个字符
'hello'

需要注意的是,对于可变序列(如列表),切片操作会返回一个新的列表;而对于不可变序列(如字符串、元组),切片操作会返回一个新的字符串或元组。

重复的字符串(不会)

栈与队列

用栈实现队列232

class MyQueue:

    def __init__(self):
        """
        in主要负责push,out主要负责pop
        """
        self.stack_in = []
        self.stack_out = []

    def push(self, x: int) -> None:
        """
        有新元素进来,就往in里面push
        """
        self.stack_in.append(x)
#pop 方法从队列头部删除元素并返回该元素。如果 stack_out 不为空,则将其栈顶元素#弹出;否则,将所有 stack_in 中的元素从后往前取出,添加到 stack_out 中,并弹出 stack_out 栈顶元素。
    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        if self.empty():
            return None
        
        if self.stack_out:
            return self.stack_out.pop()
        else:
            for i in range(len(self.stack_in)):
                self.stack_out.append(self.stack_in.pop())
            return self.stack_out.pop()    
#peek 方法返回队列头部元素,但不删除该元素。该方法可以调用 pop 方法,将结果存储在 ans 变量中,然后将 ans 添加回 stack_out 并返回它。
    def peek(self) -> int:
        ans = self.pop()
        self.stack_out.append(ans)
        return ans
        #首先调用队列的 pop 方法弹出队列头部的元素,并将其存储在变量 ans 中。
        # 然后将该元素添加到队列的 stack_out 栈中。
        # 最后返回变量 ans,即为队列的头部元素。

    def empty(self) -> bool:
        return not (self.stack_in or self.stack_out)

用队列实现栈225

from collections import deque
class MyStack:
    def __init__(self):
        self.que = deque()

    def push(self,x:int)->None:
        """
        将x压入栈顶
        """
        self.que.append(x)

    def pop(self)->int:
        """
        移除并返回栈顶元素
        """
        if self.empty():
            return None

        for i in range(len(self.que)-1):
            self.que.append(self.que.popleft())
        return self.que.popleft()


    def top(self)->int:
        """
        返回栈顶元素
        """
        ans = self.pop()
        self.que.append(ans)
        return ans
    
    def empty(self)->bool:
        return not self.que

有效的括号20

class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        mapping = {
            "(":")",
            "[":"]",
            "{":"}"
        }
        # 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false
        # 第二种情况:遍历字符串匹配的过程中,发现栈里没有我们要匹配的字符。所以return false
        # 第一种情况:此时我们已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false,否则就return true
        for item in s:
            if item in mapping.keys():
                stack.append(mapping[item])
            elif not stack or stack[-1] != item:
                return False
            else:
                stack.pop()
        return True if not stack else False

删除字符串中的所有相邻重复项1047

class Soulution:
    def removeDuplicate(self, s: str)->str:
        stack = []
        length = len(s)
        for i in range(length):
            if stack and s[i] == stack[-1]: 
                # 应该先检查 stack 是否为空,否则会导致试图访问空的 stack 列表而引发 IndexError 异常。
                stack.pop()
            else:
                stack.append(s[i])
        return ''.join(stack)

逆波兰表达式求值150

class Solution:
    def evalRPN(self,tokens:List[str]) -> int:
        stack = []
        length = len(tokens)
        opeater = {"+", "-", "*", "/"}
        for i in range(length):
            if tokens[i] in opeater:
                s1 = stack.pop()
                s2 = stack.pop()
                expre = str(int(eval(s2 + tokens[i] + s1)))
                # eval()函数将字符串表达式转换为计算结果
                stack.append(expre)
            else:
                stack.append(tokens[i])
        return int(stack[0])

⭐int() 函数会将浮点数转换为整数,截断小数部分并返回整数结果。
例如:

result = int(5 / 2)
print(result)  # 输出 2

result = int(-5 / 2)
print(result)  # 输出 -2

前K个高频元素347

from operator import itemgetter
class Solution:
     def topKFrequent(self,nums:List[int],k:int) -> List[int]:
         hanshtable = {}
         res = []
         for num in nums:
             hanshtable[num] = hanshtable.get(num, 0) + 1
         # print(hanshtable)

         new_dict = dict(sorted(hanshtable.items(), key=itemgetter(1)))
         
         for i in list(new_dict.keys())[-k:]:
             res.append(i)
             # 使用了new_dict.keys()作为添加到结果列表中的元素,这是错误的。
             # new_dict.keys()返回一个迭代器对象,而不是具体的键值。您应该改为使用list(new_dict.keys())来获取键值列表。
         return res

⭐nums[-k:] 是用于在 Python 中对列表 nums 进行切片的表达式。它返回列表的最后 k 个元素。
以下是一个示例来说明它的用法:

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
k = 3
result = nums[-k:]
print(result)

输出结果:

[8, 9, 10]

在这个示例中,nums[-k:] 返回最后三个元素 [8, 9, 10],因为 k 被设置为 3。负索引 -k 表示从列表末尾开始数的第 k 个位置。
请注意,如果 k 超过了列表的长度,它将返回整个列表的所有元素。

二叉树

二叉树的递归遍历

# 前序遍历-递归-LC144_二叉树的前序遍历
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return  [root.val] + left +  right      
        
# 中序遍历-递归-LC94_二叉树的中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if root is None:
            return []

        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)

        return left + [root.val] + right
        
 
 
# 后序遍历-递归-LC145_二叉树的后序遍历
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        left = self.postorderTraversal(root.left)
        right = self.postorderTraversal(root.right)

        return left + right + [root.val]

⭐list相加

a = [0,1]
b = [1,2]
c = [4,5]
print(a+b+c)

结果:

[0, 1, 1, 2, 4, 5]

二叉树的迭代遍历

# 前序遍历-迭代-LC144_二叉树的前序遍历
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 根结点为空则返回空列表
        if not root:
            return []
        stack = [root]
        result = []
        while stack:
            node = stack.pop()
            # 中结点先处理
            result.append(node.val)
            # 右孩子先入栈
            if node.right:
                stack.append(node.right)
            # 左孩子后入栈
            if node.left:
                stack.append(node.left)
        return result


# 中序遍历-迭代-LC94_二叉树的中序遍历
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = []  # 不能提前将root结点加入stack中
        result = []
        cur = root
        while cur or stack:
            # 先迭代访问最底层的左子树结点
            if cur:     
                stack.append(cur)
                cur = cur.left		
            # 到达最左结点后处理栈顶结点    
            else:		
                cur = stack.pop()
                result.append(cur.val)
                # 取栈顶元素右结点
                cur = cur.right	
        return result
        
        
        
# 后序遍历-迭代-LC145_二叉树的后序遍历
class Solution:
   def postorderTraversal(self, root: TreeNode) -> List[int]:
       if not root:
           return []
       stack = [root]
       result = []
       while stack:
           node = stack.pop()
           # 中结点先处理
           result.append(node.val)
           # 左孩子先入栈
           if node.left:
               stack.append(node.left)
           # 右孩子后入栈
           if node.right:
               stack.append(node.right)
       # 将最终的数组翻转
       return result[::-1]

翻转二叉树226

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return root

        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left, root.right = right, left
        return root

中结点先处理
result.append(node.val)
# 左孩子先入栈
if node.left:
stack.append(node.left)
# 右孩子后入栈
if node.right:
stack.append(node.right)
# 将最终的数组翻转
return result[::-1]

翻转二叉树226

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return root

        left = self.invertTree(root.left)
        right = self.invertTree(root.right)
        root.left, root.right = right, left
        return root

动态规划

爬楼梯70

错误示例

class Solution:
    def climbStairs(self,n: int)->int:
        dp = [0]*(n+1)
        dp[0] = 0
        dp[1] = 1
        dp[2] = 2
        for i in range(3, n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]

报错

IndexError: list assignment index out of range

是因为在n>=2时可能没有错,但是在n<2时会出错,因为会超出范围。
正确示例:

class Solution:
    def climbStairs(self,n: int)->int:
        dp = [0]*(n+1)
        if n < 3:
            return n
        dp[0] = 0
        dp[1] = 1
        dp[2] = 2
        for i in range(3, n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值