LeetCode日记[Python语言]更新ing...

博主分享了在LeetCode上用Python解题的经验,包括两数之和、整数反转、回文数等题目,强调了哈希映射、栈和动态规划等解题策略,并指出接雨水问题的暴力与动态规划解决方案,以及使用栈解决最小栈和岛屿数量问题的思路。
摘要由CSDN通过智能技术生成

以前也在博客里写过几个关于LeetCode里个人觉得有趣的题目,今天想想还是总结一下,这个博客以后会陆陆续续更新的,我还是简单说一下思路,贴一下代码,如果纯小白的话可能会看不懂。
我做过的题我会按照题目顺序添加进来的,我是按照题目顺序放的,看的时候也方便,下面正式开始。

1.两数之和

题目描述点这里
比较简单的题目,关键是要想到使用哈希映射来做,你甚至都不用把整个数组循环完就能出结果。

class Solution:
    def twoSum(self, nums, target):
        dic = {}
        for i, num in enumerate(nums):
            if num in dic:
                return [dic[num], i]
            else:
                dic[target - num] = i

7.整数反转

题目描述
不断除十取余,然后反着加起来就行了

class Solution:
    def reverse(self, x):
        num=0
        a = abs(x)
        while(a != 0):
            temp =a % 10
            num =num*10 +temp
            a = int(a/10)
            
        if x>0 and num <2147483647:
            return num
        elif x<0 and num <=2147483647:
            return -num
        else:
            return 0

9.回文数

题目描述

class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x < 0 or (x > 0 and x % 10 == 0):
            return False
        else:
            tmp = 0
            while x > tmp:
                tmp = tmp * 10 + x % 10
                x = x // 10
            return tmp == x or tmp // 10 == x

20.有效的括号

题目描述
提示:使用栈,这个很快的,前括号进栈,遇到后括号匹配上就出栈否则就错了

class Solution:
    def isValid(self, s):
        long=len(s)
        if long%2!=0:
            return False
        dic={"(":")","[":"]","{":"}"}
        li=[]
        for j in range(long):
            if s[j] in dic.keys():
                li.append(s[j])
            else:
                if not li:
                    return False              
                if dic[li[-1]]==s[j]:
                    li.pop()
                elif dic[li[-1]]!=s[j]:
                    return False
        return not li

21.合并两个有序链表

题目描述
两个链表都从头开始遍历,哪个数小就添加到新链表。

class Solution:
    def mergeTwoLists(self, l1: 'ListNode', l2: 'ListNode') -> 'ListNode':
        head = ListNode(0)
        ret = head
        while l1 != None and l2 != None:
            if l1.val > l2.val:
                head.next = l2
                l2 = l2.next
            else :
                head.next = l1
                l1 = l1.next
            head = head.next
        if l1 == None:
            head.next = l2
        elif l2 == None:
            head.next = l1
        return ret.next

35.插入的位置

题目描述
有些人先用 in 看一下是否在列表里,在的话返回的 target 的 .index,否则就插入然后 sort 在返回target的 .index,复杂度很高,但是运行时间可能比较短,内置函数的运行时间果然还是厉害,应该使用二分法来做,是比较好的思路

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

38.报数

题目描述
我觉得读懂这个题目就很难,读懂之后就简单了,233333·······

class Solution:
    def countAndSay(self, n: int) -> str:
        num = "1"  #初始化num
        def next_num(num):
            """
            计算出下一个num
            """
            pre_k, res, n = -1, "", len(num)
            for k,v in enumerate(num):
                if (k < n-1) and (v != num[k+1]):
                    res += str(k-pre_k) + num[k]
                    pre_k = k
                elif k == n-1:
                    res += str(k-pre_k) + num[k]
            return res  
        for i in range(1,n):
            num = next_num(num)
        return num

42.接雨水

题目描述点我
这个题是个困难题,我说两种方法,简单的和高端的。
普通方法:当然最简单的方法是暴力解题,对于数组中的每个元素,我们找出下雨后水能达到的最高位置,等于两边最大高度的较小值减去当前高度的值。这个可以试一下,但是时间复杂度是n的平方,太高了,就不说了,说一下下面的这个。
在暴力方法中,我们仅仅为了找到最大值每次都要向左和向右扫描一次。但是我们可以提前存储这个值。因此,可以通过动态编程解决。
官方有个图说明:
在这里插入图片描述
我感觉这个挺容易懂得,下面是代码:

class Solution:
    def trap(self, height: List[int]) -> int:
        lenth = len(height)
        if not lenth:
            return 0
        ans = 0
        left_nums = [0 for _ in range(lenth)]
        left_nums[0] = height[0]
        right_nums = [0 for _ in range(lenth)]
        right_nums[-1] = height[-1]
        for i in range(lenth):
            left_nums[i] = left_nums[i-1] if left_nums[i-1] > height[i] else height[i]

        for i in range(lenth-2,-1,-1):
            right_nums[i] = right_nums[i+1] if right_nums[i+1] > height[i] else height[i]

        for i in range(lenth):
            left_nums[i] = min(left_nums[i],right_nums[i]) - height[i]
            ans += left_nums[i]
        return ans

使用栈数据结构做这个题目,刚开始看了几遍都没懂原理,自己试了一遍后明白了,但是要我讲给其他人够呛。别人是这么解释的:
我们可以不用像上面那样存储最大高度,而是用栈来跟踪可能储水的最长的条形块。使用栈就可以在一次遍历内完成计算。
我们在遍历数组时维护一个栈。如果当前的条形块小于或等于栈顶的条形块,我们将条形块的索引入栈,意思是当前的条形块被栈中的前一个条形块界定。如果我们发现一个条形块长于栈顶,我们可以确定栈顶的条形块被当前条形块和栈的前一个条形块界定,因此我们可以弹出栈顶元素并且累加答案到 ans 。
要是还不懂自己带个例子进去试一下,一步一步按照程序走,应该能有所收获。

class Solution:
    def trap(self, height: List[int]) -> int:
        my_stack = []
	    ans,cur = 0, 0
	    while cur < len(height):
	        while my_stack and height[cur] > height[my_stack[-1]]:
	            top = my_stack.pop()
	            if not my_stack:
	                break
	            distance = cur - my_stack[-1] - 1
	            bounded_height = min(height[cur],height[my_stack[-1]]) - height[top]
	            ans += distance * bounded_height
	        my_stack.append(cur)
	        cur += 1
	    return ans

155.最小栈

题目描述
这个用python来做太简单了,不得不说python的列表是万能的啊

class MinStack:

    def __init__(self):
        self.stack = []   #栈的全部数据
        self.min_num = []   #返回当前最小数据

    def push(self, x: int) -> None:
        self.stack.append(x)
        if not self.min_num or x <= self.min_num[-1]:
            self.min_num.append(x)

    def pop(self) -> None:
        if self.stack.pop() == self.min_num[-1]:
            self.min_num.pop()
            
    def top(self) -> int:
        return self.stack[-1]

    def getMin(self) -> int:
        return self.min_num[-1]

200.岛屿的数量

题目描述
使用栈或者队列都可以做出来这道题,先贴一下使用栈做这道题的代码,循环整个列表,遇到一(找到了陆地)就进栈,把这个数变为2,代表是已经检查过的陆地,然后开始检测其四周有没有1,只要有1也是同样的做法,进栈,标记为2,直到其四周都没有1为止,出栈,这样一趟下来能把一个1四周相连的1都标记一遍,也就是找到了一整块陆地,count加一。把整个数组都循环下来就能找到所有的陆地。

class Solution:
    def numIslands(self, grid):
        line = len(grid)
        row = len(grid[0])
        count = 0
        dirs =[
            lambda x,y:(x,y+1),  #right
            lambda x,y:(x+1,y),  #down
            lambda x,y:(x-1,y),  #up
            lambda x,y:(x,y-1),  #left
        ]
        stack = []
        for i in range(line):
            for j in range(row):
                if grid[i][j] == "1":
                    stack.append((i,j))  #找到陆地,进栈
                    grid[i][j] = "2"  #已找到的陆地变为2
                    while stack:
                        cur_pot = stack[-1]
                        for dir in dirs:
                            next_pot = dir(*cur_pot)
                            if 0 <= next_pot[0] <= line-1 and 0 <= next_pot[1] <= row-1:  #越界检测
                                if grid[next_pot[0]][next_pot[1]] == "1":
                                    stack.append(next_pot)
                                    grid[next_pot[0]][next_pot[1]] = "2"
                                    break
                        else:
                            #周围没有陆地了,出栈
                            stack.pop()
                    count += 1
        return count

这个题使用队列也是能做的,使用栈的思想是深度优先,而队列就是广度优先了,使用队列解题的代码以后也贴出来,此博客一直在持续更新······

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值