PDD/ByteDance算法代码题—Python代码+详细注释

PDD代码题1
参考leetcode524题
难度:中等
算法:双指针

# pdd代码题
# 用例:
# s = 'applecolumn'

# word = 'acm'
# return True

# word = 'axm'
# return False

class Solution:
    def findLongestWord(self, s: str, word: str) -> str:
        i, j = 0, 0
        # word = str(word[0])
        while i < len(s) and j < len(word):
            if s[i] == word[j]:
                i += 1
                j += 1
            else:
                i += 1
            if j == len(word):
                return True
        return False

PDD代码题2
题目:1254. 统计封闭岛屿的数目
难度:中等
算法:DFS

class Solution:
    def closedIsland(self, grid: List[List[int]]) -> int:
        R = len(grid)
        C = len(grid[0])

        def dfs(grid, row, col):
            if not 0 <= row < R or not 0 <= col < C:
                return
            if grid[row][col] == 1:
                return
            grid[row][col] = 1
            dfs(grid, row - 1, col)
            dfs(grid, row + 1, col)
            dfs(grid, row, col - 1)
            dfs(grid, row, col + 1)
        # 淹没边界上的所有岛屿
        for row in range(R):
            dfs(grid, row, 0)
            dfs(grid, row, C - 1)
        for col in range(C):
            dfs(grid, 0, col)
            dfs(grid, R - 1, col)
        # 剩下的岛屿即为封闭岛屿,正常统计即可
        cnt = 0
        for row in range(R):
            for col in range(C):
                if grid[row][col] == 0:
                    cnt += 1
                    dfs(grid, row, col)
        return cnt

ByteDance代码题1
题目:179. 最大数
难度:中等
算法:int转str + 冒泡排序

# 2022.04.25
class Solution:
    def largestNumber(self, nums: List[int]) -> str:
        # 冒泡排序
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                if int(str(nums[i]) + str(nums[j])) < int(str(nums[j]) + str(nums[i])):
                    # 位置交换,和C++写法一样
                    tmp = nums[i]
                    nums[i] = nums[j]
                    nums[j] = tmp
        res = []
        for i in range(len(nums)):
            res += str(nums[i])
        # 不加判断会输出‘00’
        if res[0] == '0':
            return '0'
        return ''.join(res)

ByteDance代码题2
题目:556. 下一个更大元素 III
难度:中等
算法:
方法1:逻辑判断+位置交换
方法2:Python自带全排列函数(自己实现的回溯超时)

# 2022.04.26
class Solution:
    def nextGreaterElement(self, n: int) -> int:
        # 1. 逻辑判断+位置交换
        # int转成list(int),才能进行位置交换
        nums = str(n)
        nums = list(nums)
        nums_int = [int(i) for i in nums]
        # 倒着找第一个递减的点:一直递增的话没有更大的数--75421没有比它本身大的组合
        for i in range(len(nums_int) - 1, 0, -1):
            if nums_int[i - 1] >= nums_int[i]:
                continue
            # 找到递减的i-1位置后,再找该位置后面大于它的最小的数:21475找到4之后,再找5
            else:
                ans = inf
                for k in nums_int[i:]:
                    if k > nums_int[i - 1]:
                        ans = min(ans, k)     
                # 找到5后记录它的index               
                index = nums_int[i: ].index(ans) + i 
                # 交换4和5的位置
                tmp = nums_int[i - 1]
                nums_int[i - 1] = nums_int[index]
                nums_int[index] = tmp
                # 5换到位置后,把后面的从小到大排序
                res = nums_int[: i] + sorted(nums_int[i: ])
                # 把list[int]转int:先转list[str]再转str再转int
                numbers = [str(j) for j in res]
                str_numbers = []
                for number in numbers:
                    str_numbers += number
                str_numbers = ''.join(str_numbers)
                int_numbers = int(str_numbers)
            # 符合范围输出
            if int_numbers <= 2**31 - 1:
                return  int_numbers
        return -1
   

        # 2. 排列-回溯法
        # # Python 的 itertools.permutations 将通过 Python 中的 yield 关键字进行动态的生成与返回值,从而避免了存储所有值所带来的消耗(官解使用 ArrayList 存下了所有排列,太消耗性能了),带有 yield 关键字的函数被称为生成器(generator)
        # final = 2**31 
        # for num in itertools.permutations(str(n)):
        #     number = int(''.join(num))
        #     if number > n:
        #         final = min(final, number)
        # if  final == 2**31 :
        #     return -1
        # return final

        # 自己写回溯超时了
        # nums = str(n)
        # nums = list(nums)
        # def trackback(nums, depth, path, visited, ans):
        #     if depth == len(nums):
        #         ans.append(path[:])
        #         return
        #     for i in range(len(nums)):
        #         if i > 0 and nums[i] == nums[i - 1] and visited[i - 1] == False:
        #             continue
        #         if visited[i] == False:
        #             visited[i] = True
        #             path.append(nums[i])
        #             trackback(nums, depth + 1, path, visited, ans)
        #             path.pop()
        #             visited[i] = False
        # depth = 0
        # path = []
        # visited = [False for _ in range(len(nums))]
        # ans = []
        # trackback(nums, depth, path, visited, ans)

ByteDance代码题3
题目:5. 最长回文子串
难度:中等
算法:中心扩散法(两边扩展的双指针)

# 2022.04.23
class Solution:
    def longestPalindrome(self, s: str) -> str:
        # 处理空值和本身就是回文
        if not s: return ""
        if len(s) == 1 or s == s[::-1]: return s
        ans = s[0]
        # 中心扩散法
        def center_spread(s, left, right):
            while left >= 0 and right < len(s) and s[left] == s[right]:
                # 扩展,不是收缩
                left -= 1
                right += 1
            # return的缩进行不能搞错了
            return s[left + 1: right]
        for i in range(len(s)):
            odd = center_spread(s, i, i)
            even = center_spread(s, i, i + 1)
            ans = max(ans, odd, even, key = len)
        return ans

ByteDance代码题4
题目:81. 搜索旋转排序数组 II
难度:中等
算法:二分法
备注:本题用python函数如下三行就可以解决,但是要求是需要用二分法

# 2022.04.28
class Solution:
    def search(self, nums: List[int], target: int) -> bool:
        # python自带函数3行就能写完
        # if target in nums:
        #     return True
        # return False

        # 二分法
        if not nums:
            return False
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return True
            # 如果left和right位置数字一样,把left位置的不断continue掉
            if nums[left] == nums[right]:
                left += 1
                continue
            # 这里必须是<=,只有右边会出现这种情况,比如[1,1,1,1,1,1,1,1,1,13,1,1,1,1,1,1,1,1,1,1,1,1]遍历到[13,1,1,1,1,1,1,1,1,1,1,1,1]的时候,左边重复的已经跳过去了,但是右边还会有,这种情况去缩右边--QQQ
            if nums[mid] <= nums[right]:
                if nums[mid] < target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1                  # 缩这里--QQQ
            else:                                     
                if nums[left] <= target < nums[mid]:    
                    right = mid - 1
                else:
                    left = mid + 1                  # 否则只能落进这里,13就再也找不到了--QQQ
        return False
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值