ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【数据结构与算法(基础)】枚举问题(2)

【数据结构与算法(基础)】枚举问题(2) 循环遍历枚举到新的值时都要根据题意思考——①我应该维护存储的是什么②我查询时计算的是什么一般都是先查询计算再更新目录1679. K 和数对的最大数目——理清楚思路之后简单多了面试题 16.24. 数对和219. 存在重复元素 II2260. 必须拿起的最小连续卡牌数2001. 可互换矩形的组数2815. 数组中的最大数对和3623. 统计梯形的数目 I2364. 统计坏数对的数目 ——代码还是简单的就是需要一点点数学思想看了一下提示要反向思考3805. 统计凯撒加密对数目3371. 识别数组中的最大异常值3761. 镜像对之间最小绝对距离1010. 总持续时间可被 60 整除的歌曲2748. 美丽下标对的数目1679. K 和数对的最大数目——理清楚思路之后简单多了——用字典储存左侧已经遍历过的列表哈希表表示左侧出现过的数字查询计算——是否存在 k-num更新——放入新的 cnt[num]1class Solution: def maxOperations(self, nums: List[int], k: int) - int: cntdefaultdict(int) ans0 for num in nums: if cnt[k-num] ! 0: ans1 cnt[k-num] - 1 continue cnt[num]1 return ans面试题 16.24. 数对和——和上一题没什么区别只是统计答案时需要把数组存起来更新也是一样的查询计算——是否存在 target-num如果有要更新cnt[target-num]-1更新——放入新的 cnt[num]1class Solution: def pairSums(self, nums: List[int], target: int) - List[List[int]]: cntdefaultdict(int) ans[] for num in nums: if cnt[target-num] ! 0: ans.append([(target-num),num]) cnt[target-num]-1 continue cnt[num]1 return ans219. 存在重复元素 II——也可以用滑动窗口这里只讲枚举的做法这里是直接查找到了就返回不需要存答案查询计算——numPosition[x] !0 and i-numPosition[x]1 k更新——numPosition[x]i1class Solution: def containsNearbyDuplicate(self, nums: list[int], k: int) - bool: numPositiondefaultdict(int) for i,x in enumerate(nums): if numPosition[x] !0 and i-numPosition[x]1 k: return True numPosition[x]i1 return FalsePS因为枚举真的是很简单的算法题目可以从枚举中窥见很多基础的点比如很多时候我们并不是在计算上花时间很多题目可能一眼看过去知道计算方法但是还是不知道如何算实际上是对数据的处理出了问题给你的数据的形式输入—转化—计算需要的数据形式—转化—需要输出的答案的形式输出得出答案的方法算法2260. 必须拿起的最小连续卡牌数——和上一道题类似这里需要通过min更新新的答案查询计算——ansmin(ans,i-cardPosition[card]1)更新——cardPosition[card]iclass Solution: def minimumCardPickup(self, cards: List[int]) - int: cardPosition{} ansinf for i,card in enumerate(cards): if card in cardPosition: ansmin(ans,i-cardPosition[card]1) cardPosition[card]i if ans inf: return -1 return ans2001. 可互换矩形的组数——cnt计宽高比相同的矩阵数anscnt[temp]更新新的答案查询计算——anscnt[rectangle[0]/rectangle[1]]更新——cnt[rectangle[0]/rectangle[1]]1class Solution: def interchangeableRectangles(self, rectangles: List[List[int]]) - int: cntdefaultdict(int) ans0 for rectangle in rectangles: temprectangle[0]/rectangle[1] if cnt[temp]!0: anscnt[temp] cnt[temp]1 return ans2815. 数组中的最大数对和——灵神用长度为10的数组来维护我是用字典来维护差不多的思路反正也是更新维护查询计算——ans max(ans,numList[s]num)更新—— numList[s]max(numList[s],num)class Solution: def maxSum(self, nums: List[int]) - int: #感觉就是多加了一个数位的判断这种行为的意义究竟在哪里 ans-1 numListdefaultdict(int) for num in nums: s max(map(int, str(num))) if numList[s]!0: ans max(ans,numList[s]num) numList[s]max(numList[s],num) return ans3623. 统计梯形的数目 I——我是分别用两个哈希表存储点和线的数量每一轮更新水平面点和线的数量查询计算——ansdot[y]*(total-line[y])更新——total-line[y]line[y] dot[y]dot[y] 1totalline[y]class Solution: def countTrapezoids(self, points: List[List[int]]) - int: dotdefaultdict(int) linedefaultdict(int) total0 ans0 for point in points: ypoint[1] if dot[y]!0: ansdot[y]*(total-line[y]) total-line[y] line[y] dot[y] dot[y] 1 totalline[y] return ans % (10**9 7)灵神的解法——灵神是调用了Counter()先统计了每一行水平线有多少个点再对每一行遍历2364. 统计坏数对的数目 ——代码还是简单的就是需要一点点数学思想看了一下提示要反向思考——代码还是简单的就是需要一点点数学思想看了一下提示要反向思考所有数组的总数-好数对的个数坏数对的个数查询计算——anscnt[x-i]更新——cnt[x-i]1nniclass Solution: def countBadPairs(self, nums: List[int]) - int: n0 ans0 cntdefaultdict(int) for i,x in enumerate(nums): anscnt[x-i] cnt[x-i]1 nni return n-ans3805. 统计凯撒加密对数目——这道题就两点①对获得的字符串进行处理成方便计算的形式②用元组当作key查询计算——ans cnt[key]更新—— cnt[key] 1class Solution: def countPairs(self, words: List[str]) - int: cnt defaultdict(int) ans 0 for word in words: base ord(word[0]) key [] for c in word: key.append((ord(c) - base) % 26) key tuple(key) ans cnt[key] cnt[key] 1 return ans3371. 识别数组中的最大异常值——这道题是我疏忽了没有想到可以转化为两数之和对于时间复杂度也需要注意可以使用sumcounter……枚举x特殊字符和枚举y异常值是不同的解法查询计算——ans max(ans,x)更新在最开始就统计完了——totalsum(nums)cntCounter(nums)class Solution: def getLargestOutlier(self, nums: List[int]) - int: totalsum(nums) cntCounter(nums) ans-inf for x in nums: cnt[x]-1 if (total-x)%20 and cnt[(total-x)//2]0: ans max(ans,x) cnt[x]1 return ans3761. 镜像对之间最小绝对距离——y mirror(x)查询计算——cnt[y] i更新——answer min(answer, i - cnt[x])class Solution: def minMirrorPairDistance(self, nums: List[int]) - int: def mirror(num: int): ans 0 while num: temp num % 10 ans ans * 10 temp num // 10 return ans answer inf cnt {} for i, x in enumerate(nums): y mirror(x) if x in cnt: answer min(answer, i - cnt[x]) cnt[y] i return answer if answer ! inf else -11010. 总持续时间可被 60 整除的歌曲——怎么说呢看到“60”的倍数这一点就应该要想到取模的……QAQ依旧是在数据处理上犯浑了data处理先把所有的数据转化成方便计算和统计的需要的数据才是对的y(60-x) % 60xx%60查询计算——anscnt[y]更新——cnt[x]1class Solution: def numPairsDivisibleBy60(self, time: List[int]) - int: ans0 cntdefaultdict(int) for x in time: y(60-x) % 60 xx%60 if y in cnt: anscnt[y] cnt[x]1 return ans2748. 美丽下标对的数目——我的想法很复杂多少有点暴力牺牲了存储但是不用计算 灵神的就是计算量更大了xjx%10xiint(str(x)[0])查询计算——anscnt[y]更新——cnt[xi]1class Solution: def countBeautifulPairs(self, nums: List[int]) - int: cntdefaultdict(int) ans0 gcdnum{1:[1,2,3,4,5,6,7,8,9], 2:[1,3,5,7,9], 3:[1,2,4,5,7,8], 4:[1,3,5,7,9], 5:[1,2,3,4,6,7,8,9], 6:[1,5,7], 7:[1,2,3,4,5,6,8,9], 8:[1,3,5,7,9], 9:[1,2,4,5,7,8] } for x in nums: xjx%10 xiint(str(x)[0]) for y in gcdnum[xj]: anscnt[y] cnt[xi]1 return ans
返回列表