rongyao425 1
s = input().strip() op = 0 if s[0] == '+': s = s[1:] elif s[0] == '-': op = 1 s = s[1:] num = int(s) if op == 1: num = -num if num>pow(2,31)-1: print('INT_MAX') elif num<-pow(2,31): print('INT_MIN') else: print(num)
rongyao425 2
l = list(input().split()) # print(l) p = float(l[0]) M = int(l[1]) lower = int(l[2]) upper = int(l[3]) def calculate_C(a,b): up = 1 lo = 1 i = 1 while i<=b: up *= a a -= 1 lo *= i i += 1 return up/lo result = 0 for i in range(lower,upper+1): C = calculate_C(M,i) p_i = C * pow(p,i)*pow(1-p,M-i) result += p_i print("{:1.2f}".format(result))
rongyao0425 3
s_list = list(map(str,input().strip().split(','))) # print(s_list) # 前缀和,从1开始 pre_s = [0 for _ in range(len(s_list) + 1)] for i in range(len(s_list)): pre_s[i+1] = pre_s[i] + len(s_list[i]) # print(pre_s) n = int(input()) word_list = [] word_count = 0 # 双指针 i = 0 j = 1 while j < len(s_list) +1: word_count = pre_s[j] - pre_s[i] + j-i-1 if word_count > n: tmp_list = [] for k in range(i+1,j): tmp_list.append(k) word_list.append(tmp_list) i = j-1 word_count = 0 else: j += 1 tmp_list = [] for k in range(i+1,j): tmp_list.append(k) word_list.append(tmp_list) print(word_list) # 模拟 for k in range(len(word_list)): l = word_list[k] word_length = pre_s[l[-1]] - pre_s[l[0]-1] word_row = "" if k == len(word_list)-1: for i in range(len(l)): word_row += s_list[l[i]-1] + "#" tmp = n-len(word_row) word_row += "#"*tmp elif len(l) == 1: tmp = n-word_length word_row = s_list[l[0]-1] + tmp*"#" elif (n-word_length)%(len(l)-1) != 0: tmp = (n-word_length)//(len(l)-1) remain = n-word_length - tmp*(len(l)-1) for i in range(len(l)): if i != len(l)-1: word_row += s_list[l[i]-1] + "#"*tmp if remain != 0: word_row += "#" remain -= 1 word_row += s_list[l[i]-1] else: tmp = (n-word_length)//(len(l)-1) for i in range(len(l)): if i != len(l)-1: word_row += s_list[l[i]-1] + "#"*tmp word_row += s_list[l[i]-1] print(word_row)
huawei426 1
import collections N = int(input().strip()) # 入度 indegree = [0 for _ in range(N+1)] # 出度节点 nx = collections.defaultdict(list) for i in range(1,N+1): l = list(map(int,input().strip().split())) indegree[i] = l[0] for j in l[1:]: nx[j].append(i) # 拓扑排序 q = collections.deque() for i in range(1,N+1): if indegree[i] == 0: q.append(i) cnt = 0 node_num = 0 while q : res = len(q) # 统计初始化次数 cnt += 1 for i in range(res): node = q.popleft() # 统计节点数 node_num += 1 for child in nx[node]: indegree[child] -= 1 if indegree[child] == 0: q.append(child) # 有环 if node_num > N: print(-1) break print(cnt)
huawei426 2
class Node: def __init__(self,val,next = None,pre = None): self.val = val self.next = next self.pre = pre lo,up = map(int,input().strip().split()) # 建立双向链表以及哈希表 hash_table = dict() id2node = dict() head = Node(-1) tail = Node(-1) tmp = head used_set = set() for i in range(lo,up+1): node = Node(i) hash_table[i] = node id2node[node] = i node.pre = tmp tmp.next = node tmp = node tail.pre = tmp # 输入操作 op_num = int(input()) for i in range(op_num): op_list = list(map(int,input().strip().split())) if op_list[0] == 1: if up - lo +1 -len(used_set)<op_list[1]: continue else: tmp = head j = 0 while j < op_list[1]: tmp = head.next used_set.add(tmp) j += 1 head.next = tmp.next elif op_list[0] == 2: node = hash_table[op_list[1]] if node in used_set: continue else: used_set.add(node) pre = node.pre next = node.next node.pre.next = next node.next.pre = pre elif op_list[0] == 3: node = hash_table[op_list[1]] if node not in used_set: continue else: used_set.remove(node) tail.pre.next = node node.next = tail tail.pre = node print(id2node[head.next])
meituan415 贪心
n = int(input()) a_list = list(map(int,input().strip().split())) b_list = list(map(int,input().strip().split())) c_list = list(map(int,input().strip().split())) d_list = [[a_list[i],b_list[i],c_list[i]] for i in range(len(a_list))] # 外 tao1 = sorted(d_list,key = lambda x:x[0]) # 内 tao2 = sorted(d_list,key = lambda x:x[1]) # 二分搜索 def binary_search(l_list,target): l = 0 r = len(l_list) while l<r: mid = (l+r)//2 if l_list[mid][0] > target: r = mid elif l_list[mid][0] <= target: l = mid + 1 elif l == 0 and r ==0 and mid == 0: return -1 return l-1 # 每次找满足条件的外最大的 size_ = float('inf') cost = 0 per = 0 pre_idx = 0 while True: idx= binary_search(tao1,size_) if idx == -1: break if size_ != float('inf'): tao2[pre_idx][1] -= tao1[idx][0] pre_idx = idx size_ = tao1[idx][1] per = tao1[idx][2] for a,b,c in tao2: cost += b*c print(cost)
meituan415 模拟
n = int(input()) l = list(map(int,input().split())) hash_table = dict() for i in range(n+1): hash_table[i] = 0 for i in l: hash_table[i] += 1 for key in hash_table: if hash_table[key] > 1 and key<n: hash_table[key] -= 1 hash_table[key+1] += 1 for i in range(n+1): if hash_table[i] == 0: print(i) break
rongyao422 bfs
import collections l = list(map(int,input().strip().split())) q = collections.deque() for i in range(0,(len(l)+1)//2): q.append(i) n = len(q) node = 0 path = 1 flag = True # bfs while q: idx = q.popleft() node += 1 if l[idx] + idx == len(l)-1: print(path + 1) flag =False break elif l[idx] +idx>len(l): pass else: q.append(idx+l[idx]) if node == n: path += 1 node = 0 n = len(q) if flag: print(-1)
rongyao0422 3
n,m = map(int,input().strip().split()) height = [[0]*m for _ in range(n)] for i in range(n): height[i] = list(map(int,input().strip().split())) x,y,z,w = map(int,input().strip().split()) dp = {} dirs = [[1,0],[-1,0],[0,1],[0,-1]] # dp + dfs(dp的顺序) def dfs(i,j): if i==z and j == w: return 1 # 记忆化搜索 if (i,j) in dp: return dp[(i,j)] cur = 0 for nx,ny in dirs: if nx+i>=n or ny+j>=m or nx+i<0 or ny+j<0 or height[i][j]>=height[i+nx][j+ny]: continue cur += dfs(nx+i,ny+j) dp[(i,j)] = cur return cur print(dfs(x,y))
huawei0506 3
import collections n = int(input().strip()) k = int(input().strip()) k_list = list(map(int,input().strip().split())) k_list = [(k_list[i],k_list[i+1]) for i in range(len(k_list))if i %2 == 0] girl_boy = list(map(int,input().strip().split())) girl = girl_boy[:2] boy = girl_boy[2:] map_ = [] for i in range(n): line = list(input().strip().split()) map_.append(line) q = collections.deque() # 添加时间维度,判断第几层,适用于bfs中需要判断层次的题目 q.append((boy[0],boy[1],0)) flag = True while len(q) != 0: if flag == False: break tmpx,tmpy,time = q.popleft() for pulsx,plusy in [0,0],[0,1],[1,0],[-1,0],[0,-1]: x = tmpx+pulsx y = tmpy+plusy if x >=n or y >=n or x < 0 or y < 0: continue elif map_[x][y][(time+1)%3] == '1' or (x,y) in k_list: continue else: if [x,y] == girl: flag =False break else: q.append((x,y,time+1)) print(time+1)
leecode 121
# 交易一次,套用交易k次的板子 class Solution: def maxProfit(self, prices): # k笔交易 # 2*k个变量 k = 1 l = prices buy_list = [-l[0]]*k sell_list = [0]*k if len(l) == 1: return 0 else: for i in range(1,len(l)): for j in range(k): if j == 0: buy_list[j] = max(buy_list[j],-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) else: buy_list[j] = max(buy_list[j],sell_list[j-1]-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) return max(sell_list) if __name__ == "__main__": prices = [1,4,2] solution = Solution() ans = solution.maxProfit(prices) print(ans)
leecode122
# 任意交易,连个变量,类似于k次交易的板子,只不过对第一次交易不用特殊处理,因为 # 这个板子用两个变量存储了多次交易的收益,没有数组就不存在溢出的风险 #dp1 dp0分别代表买了股票和卖了股票 class Solution: def maxProfit(self, prices: List[int]) -> int: l = prices dp0 = -l[0] dp1 = 0 if len(l) == 1: return 0 for i in range(1,len(l)): dp0,dp1= max(dp0,dp1-l[i]),max(dp0+l[i],dp1) return dp1
leecode123
# 两笔交易 # 3 3 5 0 0 3 1 4 # 6 # 四个转移变量 # 套用k次交易的板子 class Solution: def maxProfit(self, prices): # k笔交易 # 2*k个变量 k = 2 l = prices buy_list = [-l[0]]*k sell_list = [0]*k if len(l) == 1: return 0 else: for i in range(1,len(l)): for j in range(k): if j == 0: buy_list[j] = max(buy_list[j],-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) else: buy_list[j] = max(buy_list[j],sell_list[j-1]-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) return max(sell_list)
leecode188
# k笔交易 # 2*k个变量 # 注意临界值的处理 j == 0(第一次交易),用了数组来存储, # k次交易的收益,存在溢出风险 class Solution: def maxProfit(self, k: int, prices: List[int]) -> int: # k笔交易 # 2*k个变量 l = prices buy_list = [-l[0]]*k sell_list = [0]*k if len(l) == 1: return 0 else: for i in range(1,len(l)): for j in range(k): if j == 0: buy_list[j] = max(buy_list[j],-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) else: buy_list[j] = max(buy_list[j],sell_list[j-1]-l[i]) sell_list[j] = max(sell_list[j],buy_list[j]+l[i]) return max(sell_list)
leecode309
# 任意交易且包含冷冻期,套用任意交易的板子 # dp0 dp1分别代表买了股票和卖了股票的收入,,dp2存储t-2时刻的卖出股票的收入 class Solution: def maxProfit(self, prices): l = prices dp0 = -l[0] dp1 = 0 dp2 = 0 if len(l) == 1: return 0 for i in range(1,len(l)): dp0 = max(dp0,-l[i] +(dp2 if i>1 else 0)) # 要注意dp2的位置 dp2 = dp1 dp1 = max(dp1,dp0+l[i]) return dp1
leecode 741
#和任意次数交易一样,只需要减去手续费 class Solution: def maxProfit(self, prices, fee) -> int: l = prices dp0 = -l[0] dp1 = 0 if len(l) == 1: return 0 for i in range(1,len(l)): dp0,dp1= max(dp0,dp1-l[i]),max(dp0+l[i]-fee,dp1) return dp1
快排求top-k
import random class Solution: def findKthLargest(self, nums, k): l = 0 r = len(nums) - 1 target = len(nums) - k while True: piviotIndex = self.partion(l,r,nums) if piviotIndex == target: return nums[piviotIndex] elif piviotIndex > target: r = piviotIndex - 1 else: l = piviotIndex + 1 def partion(self,l,r,nums): randomindex = random.randint(l,r) nums[l],nums[randomindex] = nums[randomindex],nums[l] piviot = nums[l] piviot_index = l # 不能丢,否则容易超时 l = l + 1 while True: while l<=r and nums[l] < piviot: l += 1 while l<=r and nums[r] > piviot: r -= 1 if l >= r: break nums[l],nums[r] = nums[r],nums[l] # 不能丢,否则容易超时,特别是没有走上面两个循环的时候 l += 1 r -= 1 nums[r],nums[piviot_index] = nums[piviot_index],nums[r] return r if __name__ == "__main__": solution = Solution() nums = [3,2,1,5,6,4] k = 2 ans = solution.findKthLargest(nums,k) print(ans)
取两个或两个以上的数字
# 动态规划 """ 首先,一个长度为n的数组最多能取出n-1个单调序列(如果整个数组是单调递增或者单调递减的话)。所以,我们可以从长度为2的序列开始,一直枚举到长度为n的序列,对于每个长度,统计可以取出的单调序列的个数即可。 具体实现可以用一个二维数组dp来辅助计算,其中dp[i][j]表示以第i个数结尾,长度为j的单调递增子序列的个数。转移方程为: dp[i][j] = dp[k][j-1] + 1,其中0 <= k < i,且a[k] < a[i] 这个方程的含义是,以第i个数结尾,长度为j的单调递增子序列的个数,等于以前面任意一个比它小的数k结尾,长度为j-1的单调递增子序列的个数,再加上自己构成的长度为2的序列。这样,当枚举到长度为n的序列时,可以把所有dp[n][j]累加起来,得到所有长度为j的单调递增子序列的个数。同理,可以再用一个dp数组来计算单调递减子序列的个数,最后把两个结果相加即可。 """ ### 仅仅实现递增的部分 # 注意可以实现用一个数组存储离l[k]最近的比它小的数,降低时间复杂度 def find_latest_min(l,base_index,find_index): for i in range(find_index,-1,-1): if l[i] < l[base_index]: return i return -1 l = list(map(int,input().strip().split())) latest_min = [0] * len(l) for i in range(1,len(l)): if l[i]>l[i-1]: latest_min[i] = i - 1 elif l[i]>l[latest_min[i-1]]: latest_min[i] = latest_min[i-1] else: latest_min[i] = find_latest_min(l,i,latest_min[i-1]) # 动态规划,以i结尾的递增序列 dp = [1]*len(l) for i in range(1,len(l)): if latest_min[i] != -1: dp[i] = dp[latest_min[i]] + 1 else: dp[i] = 1 # print(dp) # 求和 sum_ = 0 for i in range(len(dp)): if dp[i]>=2: sum_ += dp[i]-2+1 print(sum_)
编辑距离
""" horse ros 3 """ s1 = input().strip() s2 = input().strip() dp = [[0]*(len(s2)+1) for _ in range(len(s1)+1)] for i in range(len(s1)+1): for j in range(len(s2)+1): if i == 0 or j == 0: if i== 0: dp[0][j] = j else: dp[i][0] = i elif s1[i-1] == s2[j-1]: dp[i][j] = dp[i-1][j-1] else: # dp[i][j-1]是在s1[i-1]后添加一个字符s1[j-1],dp[i-1][j]是删除s1[i-1],dp[i-1][j-1]是修改s1[i-1]为s2[j-1] dp[i][j] = min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1]) + 1 print(dp[len(s1)][len(s2)])
leecode 295数据流的中位数
import heapq class MedianFinder: def __init__(self): self.que_min = [] self.que_max = [] def addNum(self, num: int) -> None: if not self.que_max or num<=-self.que_max[0]: heapq.heappush(self.que_max,-num) if len(self.que_min) + 1 <len(self.que_max): heapq.heappush(self.que_min,-heapq.heappop(self.que_max)) else: heapq.heappush(self.que_min,num) if len(self.que_min)>len(self.que_max): heapq.heappush(self.que_max,-heapq.heappop(self.que_min)) def findMedian(self) -> float: if len(self.que_max)>len(self.que_min): return -self.que_max[0] else: return (-self.que_max[0]+self.que_min[0])/2
翻转链表
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next # 原地翻转(有递归版本和迭代版本) # 维护pre cur 和 next,让cur的next指针域指向前面 class Solution: def reverseList(self, head): cur = head if cur!=None: next = cur.next else: return None pre = None while cur!=None: cur.next = pre pre = cur cur = next if next!=None: next = next.next return pre # 头插法(有原地和需要空间版本。原地版本让后面节点不断插到前面节点,空间版本如同构建链表一样,头插法)
无重复的最长子串
class Solution: def lengthOfLongestSubstring(self, s: str) -> int: start = 0 end = 0 max_num = 0 # 存下目前子串中所有字符 hash_set = set() while end<len(s): if s[end] not in hash_set: hash_set.add(s[end]) max_num = max(max_num,end-start+1) end += 1 else: while start < len(s) and s[start]!=s[end]: # 移除不在子串中的字符 hash_set.remove(s[start]) start += 1 # 加上相等的这个 hash_set.add(s[start]) start += 1 max_num = max(end-start+1,max_num) end += 1 return max_num if __name__ == "__main__": solution = Solution() s = "tmmzuxt" ans = solution.lengthOfLongestSubstring(s) print(ans)
二叉树的最大直径
# Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): # self.val = val # self.left = left # self.right = right class Solution: def diameterOfBinaryTree(self, root: TreeNode) -> int: # 注意+1和的细小操作 self.ans = 0 def dfs(node): if node == None: return 0 L = dfs(node.left) R = dfs(node.right) self.ans = max(self.ans,L+R) return max(L,R) + 1 dfs(root) return self.ans
柱状图中最大的矩形
class Solution: def largestRectangleArea(self, heights): stack = [] ans = 0 heights = [0] + heights + [0] for i in range(len(heights)): while stack and heights[stack[-1]]>heights[i]: tmp = stack.pop() ans = max(ans,(i-stack[-1]-1)*heights[tmp]) stack.append(i) return ans if __name__ == "__main__": l = [2,1,5,6,2,3] solution = Solution() ans = solution.largestRectangleArea(l) print(ans)
meituan0513 第三题
n = int(input().strip()) l = list(map(int,input().strip().split())) cnt = n//2 i,j = 0,0 if n % 2 == 0 : i = n//2 j = n//2+1 else: i = n//2 j = n//2+2 dic = {l[i]:i for i in range(n)} while i > 0: if dic[i]<dic[j]: cnt -= 1 if dic[i-1]<dic[i] and dic[j+1]>dic[j]: i -= 1 j += 1 else: break print(cnt)
huawei 0510 3 迪杰斯特拉
关键点:#优先队列储存下一步可选路径
# 路径长度数组
#迪杰斯特拉算法,本题加了一个自身节点的消耗,但是基本思想都一样
#最长的路径为源节点到终结点点路径
import heapq from collections import defaultdict n = int(input()) m = int(input()) systime = defaultdict(int) nxs = defaultdict(list) for _ in range(m): s,d,t = map(int,input().strip().split()) if s == d: systime[s] = t else: nxs[s].append((d,t)) start = int(input()) h = [] #储存下一步可选路径 heapq.heappush(h,(0,start)) dis = [float('inf') for _ in range(n+1)] # 路径长度数组 dis[start] = 0 # 迪杰斯特拉 while h: time,node = heapq.heappop(h) for nx,nxtime in nxs[node]: if dis[nx] > time +systime[nx]+nxtime: heapq.heappush(h,(time +systime[nx]+nxtime,nx)) dis[nx] = time +systime[nx]+nxtime # 最长的路径为源节点到终结点点路径 cnt = 0 res = 0 for d in dis: if d != float('inf'): cnt += 1 res = max(res,d) print(cnt,res)
联通子图个数 使用并查集后,根节点的数量为联通子图的个数
class UnionFind: def __init__(self): self.pair = list(range(50001)) def find(self,x): if x != self.pair[x]: x = self.find(self.pair[x]) return self.pair[x] def union(self,x,y): px,py = self.find(x),self.find(y) self.pair[py] = px class Solution: def countComponents(self, n, edges): uf = UnionFind() for e in edges: uf.union(e[0],e[1]) # 根节点的数量为联通子图的个数 seen = set() for i in range(n): pa = uf.find(i) seen.add(pa) return len(seen)
二叉树转化为先序链表
class Solution: def flatten(self, root: TreeNode) -> None: curr = root while curr: if curr.left: predecessor = nxt = curr.left while predecessor.right: predecessor = predecessor.right predecessor.right = curr.right curr.left = None curr.right = nxt curr = curr.right """ 注意到前序遍历访问各节点的顺序是根节点、左子树、右子树。如果一个节点的左子节点为空,则该节点不需要进行展开操作。如果一个节点的左子节点 不为空,则该节点的左子树中的最后一个节点被访问之后,该节点的右子节点被访问。该节点的左子树中最后一个被访问的节点是左子树中的最右边的节 点,也是该节点的前驱节点。因此,问题转化成寻找当前节点的前驱节点。 具体做法是,对于当前节点,如果其左子节点不为空,则在其左子树中找到最右边的节点,作为前驱节点,将当前节点的右子节点赋给前驱节点的右子节 点,然后将当前节点的左子节点赋给当前节点的右子节点,并将当前节点的左子节点设为空。对当前节点处理结束后,继续处理链表中的下一个节点,直 到所有节点都处理结束。 """
leecode 377 排列数 动态规划
固定背包,遍历元素是排列
固定元素,遍历背包是组合
class Solution: def combinationSum4(self, nums: List[int], target: int) -> int: dp = [1] + [0] * target for i in range(1,target+1): for num in nums: if num <= i: dp[i] += dp[i-num] return dp[target]
快速排序
def qsort(nums,l,r): if l >= r: return low = l high = r key = nums[low] while l < r: while l<r and nums[r]>key: r -= 1 nums[l] = nums[r] while l< r and nums[l]<= key: l += 1 nums[r] = nums[l] nums[l] = key qsort(nums,low,l-1) qsort(nums,l+1,high) nums = [5,3,6,4,1,2,8,7] qsort(nums,0,len(nums)-1) print(nums)
归并排序
自顶向下 非原地
def mergesort(seq): if len(seq)<=1: return seq mid = len(seq)//2 left = mergesort(seq[:mid]) right = mergesort(seq[mid:]) return merge(left,right) def merge(left,right): result = [] i = 0 j = 0 while i < len(left) and j < len(right): if left[i]<=right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result seq = [5,3,0,6,1,4] print(seq) result = mergesort(seq) print(result)
快排 自地底部向上 原地
""" 在 merge_sort 函数中,我们使用 size 变量表示归并的子数组大小。首先将 size 初始化为 1,然后循环进行归并操作,每次将 left 指针从 0 开始,每次循环时将 left 指针向右移动 size 步,同时计算 mid 和 right 指针的位置。然后调用 merge 函数对两个有序子数组进行归并。 在 merge 函数中,我们使用两个指针 i 和 j 分别指向两个子数组的开头,并比较两个子数组中的元素大小。如果右侧子数组中的元素更小,则将它插入到左侧子数组中。为了实现原地排序,我们需要将左侧子数组中大于当前元素的所有元素向右移动一个位置,然后再将当前元素插入到相应的位置。 这样,我们就可以实现原地归并排序。 """ def merge_sort(arr): n = len(arr) size = 1 while size < n: left = 0 while left < n: mid = left + size - 1 if mid >= n - 1: break right = min(mid + size, n - 1) merge(arr, left, mid, right) left = right + 1 size *= 2 def merge(arr, left, mid, right): i = left j = mid + 1 while i <= mid and j <= right: if arr[i] > arr[j]: temp = arr[j] for k in range(j, i, -1): arr[k] = arr[k - 1] arr[i] = temp j += 1 mid += 1 i += 1 return arr seq = [5,3,0,6,1,4] print(seq) merge_sort(seq) print(seq)