Home

lc273.整数转换英文表示

题目链接 这个题好像没啥好多说的,很多边界条件。1是我写的,2是我复制的官方题解,2稍微快一点应该是因为没做int到str的转化,我反正做了省得要用1000取模和余数之类的。这个算法的时间复杂度是O(N),空间复杂度是O(1)。 class Solution: def numberToWords1(self, num: int) -> str: if num == 0: return "Zero" snum = str(num) length = len(snum) while length % 3 != 0: snum = "0" + s...

Read more

lc238.除自身以外数组的乘积

题目链接 嗯感觉这题和一个剑指里的题目很相似,都是说不能使用除法。哦看了一眼,其实是完全一样的两个题目。这个算法的时间复杂度是O(N),空间复杂度是O(N)。啊还有一种方式是分别计算上下三角而不是一开始把一层的不同两边对齐。我们首先先算下三角below,算出来之后按逆序将nums里的数字依次相乘来算出每个位置的上三角above并且乘以对应位置下上角的数字得到结果。这样可以在维持时间复杂度的情况下将空间复杂度降到O(1)(因为数组是返回的数组所以不计入空间复杂度的计算)。 class Solution: def productExceptSelf1(self, nums: List[int]) -> List[int]: left_product, ri...

Read more

lc1049.最后一块石头的重量II

题目链接 啊啊啊看到题就知道应该是用动态规划,但是具体怎么做好像没什么思路。然后点开题解,就看到其实可以转换成”将石头分成两堆,不断缩小两堆石头重量的差值,最小差值即为最小剩余重量“,机智啊,这就转换成01背包问题了啊。 哦不过我又忘了01背包咋做了,虽然参考之前的“分割等和子集”写出来了但是好像不知道怎么把得到的结果转化成答案…哦发现错误了,原来是因为我的最大重量是上取整的,改成下取整就对了。这个算法的时间复杂度是O(N),空间复杂度是O(NM)。然后实现2是优化了空间之后的,空间复杂度给减少到了O(N)。 class Solution: def lastStoneWeightII1(self, stones: List[int]) -> int: ...

Read more

lc054.螺旋矩阵

题目链接 啊这个题就是典型的模拟嘛,就是要处理好各种边界吧,所以我花了很多时间在试,最后终于写对了,但是空间复杂度居然比较高?不知道为什么,试试不要写成类的方法而是都写在一个函数里。这个算法的时间复杂度O(NM),空间复杂度是O(1)。 class Solution: def spiralOrder(self, matrix: List[List[int]]) -> List[int]: if not matrix: return [] def right(x, y, time): for i in range(time, col-time): res.a...

Read more

mq035.两数之和

题目链接 为了做三数之和先把这个复习了一边,这个算法的时间复杂度是O(N),空间复杂度是O(N)。 class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: hashtable = {} for i in range(len(nums)): if nums[i] in hashtable: return [i, hashtable[nums[i]]] else: hashtable[target-nums[i]] = i

Read more

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

题目链接 啊感觉这个题做过的,然后自己写了一下,倒是过了示例,但是提交之后发现有特殊情况没有考虑,比如说在链表中只有一个元素的时候要删除倒数第一个节点,我的实现就会有问题,然后看了一下两年前提交的答案,发现使用的dummyt节点是在head之前的节点而非我这样将dummy设成head。另外,在这样设置dummy后,在提前走n步时我们要改成提前走n+1步。这个算法的时间复杂度是O(N),空间复杂度是O(1)。 # Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self....

Read more

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

题目链接 emmm依然按照递归的思路做了一下题,但是为什么时间上只超过了不到百分之10的人啊,难度递归真的太慢了嘛还是因为我重复查找了每一个target啊,感觉应该是因为后者吧。这个算法的时间复杂度是O(logN),空间复杂度是O(1)。嗯再看看别人怎么实现的吧。啊我知道了,因为我没有利用好数组有序的这个特性导致在递归的时候同时递归了两边的区间,而实际上只需要递归左区间或者右区间就可以了,啊我尝试更改实现1感觉如果按照2的思路的话得拆分成两个方法(除非使用targt+1的技巧,但是那样写出来应该就是和实现2把left_func拆分成一个独立的方法而已)。所以按这样看到话,我的思路慢的原因就这样花费了多余的时间去找到了每个和target值相对应的值才求出了左右边界。 class So...

Read more

mq015.搜索旋转排序数组

题目链接 嗯第一眼就感觉是二分查找法,然后我就一通乱写,就写完了,时间复杂度是O(logN),空间复杂度是O(1)。不过我这个是递归版本的而且好像并没有利用有序这个特性,所以我就又复制了一版用循环实现的。 class Solution: def search1(self, nums: List[int], target: int) -> int: self.ans = -1 left, right = 0, len(nums)-1 self.find(nums, target, left, right) return self.ans def find(self, nums, target, l...

Read more

mq014.下一个排列

题目链接 做过一个类似的生成各种不同的排列的题目,如果不是原地返回的话,可以先生成所有排列然后进行排序然后取下一个,我翻出了之前的记录写了一下给定字符生成各个排序的集合。但是这题要求原地返回并且将所有排列全都求出来也非常地浪费时间,因此必须要有一种方法能够直接求出下个排列。对于下个排列,我们有两个发现:一就是我们需要将一个左边的”较小数“与右边的一个”较大数“交换,以能够使当前排列变大,从而得到下一个排列;二就是,我们同时要让这个”较小数“尽量靠右而”较大数“尽可能小。当交换完成后,”较大数“右边的数需要按照升序重新排列,这样才能保证新排列大于原来排列的情况下,变大的幅度尽可能小。 那么如何具体实现上述的思想呢。首先,我们先找“较小数”,我们从后往前寻找第一个顺序对(i, i+1)...

Read more

mq013.三数之和

题目链接 这题可以用双指针法解决,与两数之和这题类似。难点在于题目要求返回的数组中不含有重复的数对。实现如下,其中带注释的行是有在做跳过重复字符这件事。这个算法的时间复杂度是O(N^2),空间复杂度是O(1)。 class Solution: def threeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() ans = [] for i in range(len(nums)-2): if nums[i] > 0: break if i > 0 and nums[...

Read more