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