leetcode刷题记录【数据结构类题目】—Python代码+详细注释

题目:735. 行星碰撞
难度:中等
算法:栈模拟

# 2022.07.15
class Solution:
    def asteroidCollision(self, ats: List[int]) -> List[int]:
        stack = []
        for at in ats:
            to_stack = True  # ---------AAA
            while to_stack and stack and stack[-1] > 0 and at < 0:  # 栈里的是正数,at是负数
                # 两个if里都写上等于,处理两边相等一起爆炸的情况
                if stack[-1] >= -at:  # 栈里的正数比过了at:
                    to_stack = False  # 换下一个at(while里面要写to_stack)——标记为false不入栈---AAA
                if stack[-1] <= -at:  # 栈里的正数没比过at
                    stack.pop()  # 干掉并换栈里的下一个比
            if to_stack:  # ---------AAA
                # 正数入栈,或栈里的正数都没比过负数at,就把at入栈
                stack.append(at)
        return stack

题目:565. 数组嵌套
难度:中等
算法:数组嵌套/有向图

# 2022.07.19
class Solution:
    def arrayNesting(self, nums: List[int]) -> int:
        ans = 0
        n = len(nums)
        mark = [False] * n
        for i in range(n):
            # mark数组为什么不放在这儿:因为循环过一次的数,是个环,没必要再次循环
            cnt = 0
            # 每次while循环遍历完一个环后,开始遍历下一个环;如果无环,会由while跳过;如果已被标记,会由for循环直接跳过
            while not mark[i]:
                mark[i] = True
                i = nums[i]
                cnt += 1
            ans = max(ans, cnt)
        return ans

题目:731. 我的日程安排表 II
难度:中等
算法:数组区间比较

# 2022.07.20
class MyCalendarTwo:

    def __init__(self):
        self.booked = []  # 预定过的有效区间
        self.duplicate = []  # 预定两次的区间

    def book(self, start: int, end: int) -> bool:
        # 如果跟两次重合的重合了,返回false
        if any(start < e and end > s for (s, e) in self.duplicate):
            return False
        # 如果跟一次的重合了,把重合部分加入两次重合list
        for (s, e) in self.booked:
            if start < e and end > s:
                self.duplicate.append((max(start, s), min(end, e)))
        # 没丢弃的都记录下来跟后面的继续比较
        self.booked.append((start, end))
        return True

# Your MyCalendarTwo object will be instantiated and called as such:
# obj = MyCalendarTwo()
# param_1 = obj.book(start,end)

题目:1331. 数组序号转换
难度:简单
算法:哈希表

# 2022.07.28
class Solution:
    def arrayRankTransform(self, arr: List[int]) -> List[int]:
        # 去重+排序
        tmp = sorted(set(arr))
        # 哈希
        dic = {value: index for index, value in enumerate(tmp, 1)}
        # 从哈希表中取arr中对应的index
        ans = [dic[num] for num in arr]
        return ans

题目:206. 反转链表
难度:简单
算法:反转链表

# 2022.08.12
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 迭代做法,;类似冒泡排序
        # 来个空链表
        pre = None
        # cur从头开始准备,后面会逐步转变指向
        cur = head
        while cur:
            # 创建临时节点暂存cur的下一个节点(右)
            tmp = cur.next
            # 把cur下一个节点转而指向另一侧(左)
            cur.next = pre
            # pre后移(右)
            pre = cur
            # cur后移(右)
            cur = tmp
        return pre

参考思路:https://leetcode.cn/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/

题目:165. 比较版本号
难度:中等
算法:两个数组对比

# 2022.12.11
class Solution:
    def compareVersion(self, version1: str, version2: str) -> int:
        # fillvalue来制定那些缺失值,当参数长度不一时,zip和较短的保持一致,itertools.zip_longest()和较长的保持一致。
        for ver1, ver2 in zip_longest(version1.split('.'), version2.split('.'), fillvalue = 0):
            ver1_int, ver2_int = int(ver1), int(ver2)
            if ver1_int != ver2_int:
                return 1 if ver1_int > ver2_int else -1
        return 0

# list2 = ["a", "b", "c", "d","e"]  #len = 5
# list3 = [1, 2, 3, 4]  #len = 4
# print(list(itertools.zip_longest(list1, list3, fillvalue = "克里马擦")))
# #[('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', '克里马擦')]

------------------before---------------------
20211201
题目1446. 连续字符
难度:简单
题解:一列字符串中count重复最多的个数,如果第i个和第i-1个一样,就count+1,刷新到ans中,记录下一个时把count更新为1;
注意点:i-1需要考虑边界问题

20211206
题目1005. K 次取反后最大化的数组和
难度:简单
题解:排序后count非正数的个数,(1)考虑一种特殊情况:非正数数的个数cnt小于k且相减为奇数,将不得不留成负数的(选绝对值最小的)从绝对值之和里减去;(2)其他情况,选k与cnt较小的将负数转成正数。
1005题目地址

20211228
题目475. 供暖器
难度:中等
题解:对每个house找到minimum距离的heater,称之为热水器距离,然后取所有houses的热水器距离中的最大值。(后续改代码的时候发现,其实只要比较每个house左右两个距离最近的heaters即可,不用每个heater都去比较,而且记录最小值即可,不用把整个数组存下来)

注意点:边界问题—out of range
在这里插入图片描述
没加heaters = heaters + [-inf,inf]之前,报错index out of range,基于上图用例
(1)第一次打印出来发现k有负数,由于k -= 1的存在使得k变成负数超出范围,于是加了heaters = heaters + [-inf],还是报错index out of range;
(2)第二次打印出来发现k4 = 2,使得mini = min(tmp, heaters[k]-houses[i])中的heaters[k] 超出范围,尝试把k -= 1移到前面来,但是mini = min(tmp, heaters[k]-houses[i])中的heaters[k] 实际值就不对了,于是改成加了heaters = heaters + [inf],由于heaters[k]=inf时,对式子mini = min(tmp, heaters[k]-houses[i])无影响,所以此方法行得通。
475题目地址

class Solution:
    def findRadius(self, houses: List[int], heaters: List[int]) -> int:
        # 第一次写的,把比较结果存成了数组,时间超出限制了
        # mini = [0]*len(houses)
        # tmp = [[0]*len(heaters)]*len(houses)
        # for i in range(len(houses)):
        #     mini[i] = min(list(map(abs,(houses[i] - heaters[k] for k in range(len(heaters))))))
        #     # for k in range(len(heaters)):
        #     #     tmp[i][k] =  abs(houses[i] - heaters[k])
        #     # mini[i] =  min(tmp[i])

        #     # mini[i] = min(abs(houses[i] - heaters[k] for k in heaters))
        # return max(mini)
        
        # 第二次写,每次比较结果只存成一个数(因为边界问题,打印了很多参数定位bug)
        ans, i, k = 0, 0, 0
        heaters = heaters + [-inf,inf]
        houses.sort()
        heaters.sort()
        print("houses:",houses)
        print("heaters:",heaters)

        while i < len(houses):
            tmp = inf
            print("i:",i)
            while k < len(heaters) and heaters[k] <= houses[i]:
                print("k1:",k)
                print(len(heaters))
                tmp = min(tmp, houses[i]-heaters[k])
                print("tmp:",tmp)
                k += 1
                print("k4:",k) 
            mini = min(tmp, heaters[k]-houses[i])
            print("k5:",k)
            print("mini:",mini)
            ans = max(ans, mini)
            print("ans:",ans)
            i += 1
            print("k2:",k)
            k -= 1
            print("k3:",k)
        return ans



题目1995. 统计特殊四元组
难度:简单
题解:数据范围小,直接暴力求解了,后续有空可以看看怎么降复杂度
1995题地址

2022.03.04
题目剑指 Offer 38. 字符串的排列
难度:中等
题解:回溯+【排序&去重】
38题题目地址
debug记录

s = 'abc'
nums = list(s)
nums = sorted(nums)
# 为下面去重做准备
nums = sorted(nums)
def dfs(nums, depth, path, used, ans):
    print("nums长度=",len(nums))
    print("树深depth", depth)
    print("判断下树深depth是否=nums长度")
    print("-------")
    if depth == len(nums):
        print("=======")
        print("记入答案的path",path)
        print("=======")
        ans.append(''.join(path))  # path携写成nums的时候输出了6个“abc”
        return
    for i in range(len(nums)):
        # 去重--由于已排序,从第二个起,如果和上一个字符一样且上一个没记录进路径
        print("第",i,"次进循环:")
        print("-------")
        if i > 0 and nums[i] == nums[i - 1] and used[i - 1] == False:
            print("nums[",i,"]:",nums[i]," & nums[",i-1,"]:", nums[i-1])
            continue
        if used[i] == False:
            print("判断后第",i,"次进循环:")
            print("-------")
            print("used判断后", used)
            print("-------")
         # 加入
            path.append(nums[i])
            print("加入path", path)
            print("-------")
            used[i] = True
            print("used加入后变为true值", used)
            print("-------")
         # depth+1
            print("自我执行增加树深depth=",depth)
            print("-------")
            dfs(nums, depth + 1, path, used, ans)
            print("↓↓↓↓")
            print("树深depth增加depth+1后",depth)
            print("-------")
         # 撤销
            path.pop()
            used[i] = False
            print("used撤销后变为false值", used)
            print("-------")
# 初始化
depth = 0
path = []
used = [False for _ in range(len(nums))]
ans = []
# 执行dfs函数
dfs(nums, depth, path, used, ans)
print(ans)
nums长度= 3
树深depth 0
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
判断后第 0 次进循环:
-------
used判断后 [False, False, False]
-------
加入path ['a']
-------
used加入后变为true值 [True, False, False]
-------
自我执行增加树深depth= 0
-------
nums长度= 3
树深depth 1
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
第 1 次进循环:
-------
判断后第 1 次进循环:
-------
used判断后 [True, False, False]
-------
加入path ['a', 'b']
-------
used加入后变为true值 [True, True, False]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
第 1 次进循环:
-------
第 2 次进循环:
-------
判断后第 2 次进循环:
-------
used判断后 [True, True, False]
-------
加入path ['a', 'b', 'c']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['a', 'b', 'c']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [True, True, False]
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [True, False, False]
-------
第 2 次进循环:
-------
判断后第 2 次进循环:
-------
used判断后 [True, False, False]
-------
加入path ['a', 'c']
-------
used加入后变为true值 [True, False, True]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
第 1 次进循环:
-------
判断后第 1 次进循环:
-------
used判断后 [True, False, True]
-------
加入path ['a', 'c', 'b']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['a', 'c', 'b']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [True, False, True]
-------
第 2 次进循环:
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [True, False, False]
-------
↓↓↓↓
树深depth增加depth+1后 0
-------
used撤销后变为false值 [False, False, False]
-------
第 1 次进循环:
-------
判断后第 1 次进循环:
-------
used判断后 [False, False, False]
-------
加入path ['b']
-------
used加入后变为true值 [False, True, False]
-------
自我执行增加树深depth= 0
-------
nums长度= 3
树深depth 1
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
判断后第 0 次进循环:
-------
used判断后 [False, True, False]
-------
加入path ['b', 'a']
-------
used加入后变为true值 [True, True, False]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
第 1 次进循环:
-------
第 2 次进循环:
-------
判断后第 2 次进循环:
-------
used判断后 [True, True, False]
-------
加入path ['b', 'a', 'c']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['b', 'a', 'c']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [True, True, False]
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [False, True, False]
-------
第 1 次进循环:
-------
第 2 次进循环:
-------
判断后第 2 次进循环:
-------
used判断后 [False, True, False]
-------
加入path ['b', 'c']
-------
used加入后变为true值 [False, True, True]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
判断后第 0 次进循环:
-------
used判断后 [False, True, True]
-------
加入path ['b', 'c', 'a']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['b', 'c', 'a']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [False, True, True]
-------
第 1 次进循环:
-------
第 2 次进循环:
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [False, True, False]
-------
↓↓↓↓
树深depth增加depth+1后 0
-------
used撤销后变为false值 [False, False, False]
-------
第 2 次进循环:
-------
判断后第 2 次进循环:
-------
used判断后 [False, False, False]
-------
加入path ['c']
-------
used加入后变为true值 [False, False, True]
-------
自我执行增加树深depth= 0
-------
nums长度= 3
树深depth 1
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
判断后第 0 次进循环:
-------
used判断后 [False, False, True]
-------
加入path ['c', 'a']
-------
used加入后变为true值 [True, False, True]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
第 1 次进循环:
-------
判断后第 1 次进循环:
-------
used判断后 [True, False, True]
-------
加入path ['c', 'a', 'b']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['c', 'a', 'b']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [True, False, True]
-------
第 2 次进循环:
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [False, False, True]
-------
第 1 次进循环:
-------
判断后第 1 次进循环:
-------
used判断后 [False, False, True]
-------
加入path ['c', 'b']
-------
used加入后变为true值 [False, True, True]
-------
自我执行增加树深depth= 1
-------
nums长度= 3
树深depth 2
判断下树深depth是否=nums长度
-------
第 0 次进循环:
-------
判断后第 0 次进循环:
-------
used判断后 [False, True, True]
-------
加入path ['c', 'b', 'a']
-------
used加入后变为true值 [True, True, True]
-------
自我执行增加树深depth= 2
-------
nums长度= 3
树深depth 3
判断下树深depth是否=nums长度
-------
=======
记入答案的path ['c', 'b', 'a']
=======
↓↓↓↓
树深depth增加depth+1后 2
-------
used撤销后变为false值 [False, True, True]
-------
第 1 次进循环:
-------
第 2 次进循环:
-------
↓↓↓↓
树深depth增加depth+1后 1
-------
used撤销后变为false值 [False, False, True]
-------
第 2 次进循环:
-------
↓↓↓↓
树深depth增加depth+1后 0
-------
used撤销后变为false值 [False, False, False]
-------
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值