leetcode 刷题记录,数组部分,代码随想录刷题顺序

     看了好多攻略,打算第一遍刷题顺序跟着 代码随想录 :数组、链表、哈希表、字符串、双指针法、栈与队列、二叉树、回溯算法 、贪心算法、动态规划、单调栈

      题外话:小白一枚,打算刷题提高编程能力,由于现在在公司算法部门实习,所以使用python语言,打算明年秋招之前用java或者c++再刷一遍。下面纯记录个人刷题日记及代码。

      两个月过去了……没刷几题,寒假回家躺平了,最近开始正式刷题了,看看能不能找到暑期实习吧,不打算学java了,还是老老实实冲算法吧!

代码随想录:代码随想录 (programmercarl.com)

DAY 1

704.二分查找

704. 二分查找 - 力扣(LeetCode)

class Solution1:
    def search(self, nums, target):
        left, right = 0, len(nums) - 1
        
        while left <= right:
            middle = (left + right) // 2

            if nums[middle] < target:
                left = middle + 1
            elif nums[middle] > target:
                right = middle - 1
            else:
                return middle
        return -1

emp1 = Solution1()
emp1.search([-1,3,5,7,9,14,55,48],55)
#输出:6

35.搜索插入位置

class Solution3:
    def search(self, nums, target):
        left, right = 0, len(nums) - 1
        
        while left <= right:
            middle = (left + right) // 2

            if nums[middle] < target:
                left = middle + 1
            elif nums[middle] > target:
                right = middle - 1
            else:
                return middle
        return right + 1

emp3 = Solution3()
emp3.search([-1,3,5,7,9],8)
#输出:4

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

class Solution4:
    def search(self, nums, target):
        def result(nums,target):
            left, right = 0, len(nums) - 1
            while left <= right:
                middle = (left + right) // 2
                if nums[middle] < target:
                    left = middle + 1
                elif nums[middle] > target:
                    right = middle - 1
                else:
                    return left
            return -1

        index = result(nums,target)
        if index==-1:return [-1,-1]
        left,right=index,index
        while left -1 >=0 and nums[left - 1] == target: left -=1
        while right+1 < len(nums) and nums[right + 1] == target:right +=1
        print([left,right])

emp4 = Solution4()
nums=[-1,3,5,6,7,9,9,9,9,9]
target=9
emp4.search(nums,target)
#输出:[5,9]

69.x 的平方根

方法一:

class Solution5:
    def mySqrt(self, x: int) -> int:
        l, r, ans = 0, x, -1
        while l <= r: #不能漏掉l=r的情况
            mid = (l + r) // 2
            if mid * mid <= x:
                ans = mid
                l = mid + 1
            else:
                r = mid - 1
        return ans

emp5 = Solution5()
emp5.mySqrt(9)
#输出:3

方法二:

​
class Solution6:
    def mySqrt(self, x):
        if x == 0:
            return 0
        
        x0,C = float(x),float(x)
        while True:
            xi = 0.5 * (x0 + C/x0)
            if abs(x0 - xi) < 1e-7:
                break
            x0 = xi
        return int(x0)

emp6 = Solution6()
emp6.mySqrt(10)
#输出:3

​

DAY 2

27.移除元素

方法一:双指针法,快指针、慢指针

class Solution8:
    def removeElement(self, nums,val):
        fast = 0
        slow = 0
        for fast in range(len(nums)):
            if nums[fast] == val:
                continue
            else:
                nums[slow] = nums[fast]
            slow  +=1
        return slow
          
emp8 = Solution8()
nums=[3,2,2,3]
val = 3
length=emp8.removeElement(nums,val)
for i in range(length):
    print(nums[i])
#输出:2
#      2

方法二:双指针法、左指针、右指针

class Solution9:
    def removeElement(self, nums,val):
        right = len(nums)-1
        left = 0
        while left <= right:
            if nums[left] == val:
                nums[left] = nums[right]
                right -= 1
            else:
                left  += 1
        return nums[0:left]

emp9 = Solution9()
nums=[3,2,2,2,3,6,7,5,3]
val = 2
emp9.removeElement(nums,val)
#输出:[3, 3, 5, 7, 3, 6]

26.删除有序数组中的重复项

class Solution10:
    def removeDuplicates(self, nums):
        fast = 1
        slow = 0
        for fast in range(len(nums)):
            if nums[fast] == nums[slow]:
                fast +=1
            else:
                slow  +=1
                nums[slow] = nums[fast]
                
        return nums[0:slow]

emp10 = Solution10()
nums=[3,2,2,2,3,6,7,5,3] 
emp10.removeDuplicates(nums)
#输出:[3, 2, 3, 6, 7, 5]

283.移动零

class Solution11:
    def moveZeroes(self, nums):
        right = 0
        left = 0
        for right in range(len(nums)):
            if nums[right]:
                nums[left],nums[right] = nums[right],nums[left]
                left  += 1
            right +=1
        return nums
  
emp11 = Solution11()
nums=[3,0,2,0,3,6,0] 
emp11.moveZeroes(nums)
#输出:[3, 2, 3, 6, 0, 0, 0]

844.比较含退格的字符串

class Solution12:
    def backspaceCompare(self,s,t):
        def build(str):
            ret = list()
            for i in str:
                if i != '#':
                    ret.append(i)
                elif ret:
                    ret.pop() #保证ret里面有字符才能pop
            return ret
        
        return build(s) == build(t)

emp12 = Solution12()
s='a##c'
t='#a#c'
emp12.backspaceCompare(s,t)
#输出:True

977.有序数组的平方

方法一:直接排序

class Solution13:
    def sortedSquares(self, nums):
        return sorted(num * num for num in nums)

emp13 = Solution13()
nums=(2,3,4,7,8,-1,-3)
emp13.sortedSquares(nums)
#输出:[1, 4, 9, 9, 16, 49, 64]

方法二:双指针法,重点是有序数组,最大值是最右边或者最左边、左右指针 

class Solution14:
    def sortedSquares(self, nums):
        n = len(nums)
        result = [-1]*n
        i,j,k = 0,n-1,n-1
        while i <= j:
            lm = nums[i]**2
            rm = nums[j]**2
            if lm > rm:
                result[k] = lm
                i +=1
            else:
                result[k] = rm
                j -=1
            k -=1
        return result

emp14 = Solution14()
nums=(-3,-1,0,4,6,9)
emp14.sortedSquares(nums)
#输出:[0, 1, 9, 16, 36, 81]

DAY 3

209.长度最小的子数组

滑动窗口、双指针法

class Solution15:
    def minSubArrayLen(self, nums,target):
        res = float("inf") #设为无穷大
        sum = 0
        i = 0
        for j in range(len(nums)):
            sum += nums[j]
            while sum >= target:
                res = min(res,j-i+1)
                sum -= nums[i]
                i += 1
        if res == float("inf"):
            return 0
        else:
            return res

emp15 = Solution15()
nums = (2,3,1,2,4,3)
target = 7
emp15.minSubArrayLen(nums,target )
#输出:2

DAY 4

904.水果成篮

class Solution16:
    def totalFruit(self, fruits: List[int]) -> int:
        ans = i = 0
        count = collections.Counter()
        for j, x in enumerate(fruits):
            count[x] += 1
            while len(count) >= 3:
                count[fruits[i]] -= 1
                if count[fruits[i]] == 0:
                    del count[fruits[i]]
                i += 1
            ans = max(ans, j - i + 1)
        return ans

emp16 = Solution16()
fruits = (2,3,1,2,2,1,3)
emp16.totalFruit(fruits)
#输出:4

DAY 5/6 

双休 没学

DAY 7

76. 最小覆盖子串

76. 最小覆盖子串

这个对我来说有点困难啊啊啊 

首先是我不懂enumerate返回的是什么类型的数据,然后测试了下:

s = "ADOBECODEBANC"
print(list(enumerate(s)))
for j,c in enumerate(s):
    print(j,c)

输出是:leetcode 刷题记录,数组部分,代码随想录刷题顺序_第1张图片

 用了滑窗方法,借鉴了力扣里面大佬的题解思路,官方题解没有python版本

滑动窗口思想 - 最小覆盖子串 - 力扣(LeetCode)

class Solution17:
    def minWindow(self, s: str, t: str) -> str:
        need = collections.defaultdict(int)
        for c in t:
            need[c] += 1 #记录了遍历到的所有元素,而只有need[c]>0时,代表c就是所需元素
        needCnt = len(t) #记录所需元素的总数量
        i = 0 #记录起始位置
        res = (0, float('inf'))  #用两个元素,方便之后记录起终点
        #三步骤:
        #1. 增加右边界使滑窗包含t
        for j,c in enumerate(s):
            if need[c] >0:
                needCnt -= 1
            need[c] -= 1 #这行放在外面不可以,看19行 need[c] == 0
        #2. 收缩左边界直到无法再去掉元素   !注意,处理的是i
            if needCnt == 0:
                while True:
                    c = s[i]
                    if need[c] == 0: #表示再去掉就不行了(need>0)
                        break
                    else:   #need里面<0的都是不需要的,将他们+1,且去掉,滑窗右移
                        need[c] += 1
                        i += 1
                #if j-i < res[1] - res[0]:  #这里是否减一都可以,只要每次都是这样算的就行,反正最后也是输出子串而非长度
                    res = (i,j)
        #3. i多增加一个位置,准备开始下一次循环(注意这步是在 needCnt == 0里面进行的 )
                need[s[i]] += 1
                needCnt += 1    #由于 移动前i这个位置 一定是所需的字母,因此NeedCnt才需要+1
                i += 1
        return s[res[0]: res[1]+1]

emp17 = Solution17()
s = "ADOBECODEBANC"
t = "ABC"
emp17.minWindow(s,t)
#输出:'BANC'

困难程度的题对我来说确实是困难,花了5个小时才勉强看懂算法思路,过段时间估计又忘了……

DAY 8

59. 螺旋矩阵 II
方法一:不需额外考虑中心数的情况,边界只考虑n是否达到n*n

leetcode 刷题记录,数组部分,代码随想录刷题顺序_第2张图片

class Solution19:
    def generateMatrix(self, n: int) -> [[int]]:
        l, r, t, b = 0, n - 1, 0, n - 1
        mat = [[0 for _ in range(n)] for _ in range(n)]
        num, tar = 1, n * n
        while num <= tar:
            for i in range(l, r + 1): # left to right
                mat[t][i] = num
                num += 1
            t += 1
            for i in range(t, b + 1): # top to bottom
                mat[i][r] = num
                num += 1
            r -= 1
            for i in range(r, l - 1, -1): # right to left
                mat[b][i] = num
                num += 1
            b -= 1
            for i in range(b, t - 1, -1): # bottom to top
                mat[i][l] = num
                num += 1
            l += 1
        return mat

emp19 = Solution19()
n = 3
emp19.generateMatrix(n)
#输出:[[1, 2, 3], [8, 9, 4], [7, 6, 5]]

方法二:需要额外考虑中心数,边界用左右和上下共同约束,都是左闭右开区间

leetcode 刷题记录,数组部分,代码随想录刷题顺序_第3张图片

class Solution20:
    def generateMatrix(self, n: int) -> [[int]]:
        left,right,up,down = 0,n-1,0,n-1
        number = 1
        mat = [[0]*n for _ in range(n) ]
        
        while left < right and up < down:
            for i in range(left,right):
                mat[up][i] = number
                number += 1
            for j in range(up,down):
                mat[j][right] = number
                number += 1
            for i in range(right,left,-1):
                mat[down][i] = number
                number += 1
            for j in range(down,up,-1):
                mat[j][left] = number
                number += 1
                
            left += 1
            right -= 1
            up += 1
            down -= 1
            
        # 如果阶数为奇数,额外填充一次中心
        if n % 2:
            mat[n // 2][n // 2] = number
            
        return mat

emp20 = Solution20()
n = 3
emp20.generateMatrix(n)
#输出:[[1, 2, 3], [8, 0, 4], [7, 6, 5]]

两种方法用了不同的初始化0矩阵的方法

54.螺旋矩阵

逆向推还是推不出来,我太菜了

方法一:根据上题方法二改动的

还是没明白为啥while循环体内还要嵌套个if判断条件,整不明白

class Solution22:
    def spiralOrder(self, matrix):
        if not matrix or not matrix[0]:
            return list()
        ans = []
        rows, columns = len(matrix), len(matrix[0]) 
        left,right,up,down = 0,columns - 1,0,rows - 1
        while left <= right and up <= down:
            for i in range(left,right + 1):
                ans.append(matrix[up][i])
            for j in range(up + 1,down + 1):
                ans.append(matrix[j][right])
            if left < right and up < down:  #就是这里不明白
                for i in range(right - 1,left,-1):
                    ans.append(matrix[down][i])
                for j in range(down,up,-1):
                    ans.append(matrix[j][left])
                
            left += 1
            right -= 1
            up += 1
            down -= 1
        return ans

emp22 = Solution22()
matrix = [[1, 2, 3], [4,5,6], [7, 8,9]]
emp22.spiralOrder(matrix)
#输出:[1, 2, 3, 6, 9, 8, 7, 4, 5]

方法二:我是看不懂的,python这语法我都看不懂了,只知道这个方法好像很厉害的样子

class Solution21:
    def spiralOrder(self, matrix):
        ans = []
        while matrix:
            ans += matrix.pop(0)  # 向右
            if matrix and matrix[0]: 
                ans += [row.pop(-1) for row in matrix] # 向下
            else: return ans
            if matrix: ans += matrix.pop(-1)[::-1] # 向左
            else: return ans
            if matrix and matrix[0]: ans += [row.pop(0) for row in matrix][::-1] # 向上
            else: return ans
        return ans

emp21 = Solution21()
matrix = [[1, 2, 3], [4,5,6], [7, 8,9]]
emp21.spiralOrder(matrix)
#输出:[1, 2, 3, 6, 9, 8, 7, 4, 5]

你可能感兴趣的:(leetcode,算法,动态规划)