functionbubbleSort(arr) { var len = arr.length; for (var i = 0; i < len - 1; i++) { for (var j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j+1]) { // 相邻元素两两对比 var temp = arr[j+1]; // 元素交换 arr[j+1] = arr[j]; arr[j] = temp; } } } return arr; }
选择排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
functionselectionSort(arr) { var len = arr.length; var minIndex, temp; for (var i = 0; i < len - 1; i++) { minIndex = i; for (var j = i + 1; j < len; j++) { if (arr[j] < arr[minIndex]) { // 寻找最小的数 minIndex = j; // 将最小数的索引保存 } } temp = arr[i]; arr[i] = arr[minIndex]; arr[minIndex] = temp; } return arr; }
插入排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14
function insertionSort(arr){ var len = arr.length; var preIndex, current; for (var i = 1; i < len; i++) { preIndex = i - 1; current = arr[i]; while (preIndex >= 0 && arr[preIndex] > current) { arr[preIndex + 1] = arr[preIndex]; preIndex--; } arr[preIndex + 1] = current; } return arr; }
希尔排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
functionshellSort(arr) { var len = arr.length; for (var gap = Math.floor(len / 2); gap > 0; gap = Math.floor(gap / 2)) { // 注意:这里和动图演示的不一样,动图是分组执行,实际操作是多个分组交替执行 for (var i = gap; i < len; i++) { var j = i; var current = arr[i]; while (j - gap >= 0 && current < arr[j - gap]) { arr[j] = arr[j - gap]; j = j - gap; } arr[j] = current; } } return arr; }
functionquickSort(arr, left, right) { var len = arr.length, partitionIndex, left = typeof left != 'number' ? 0 : left, right = typeof right != 'number' ? len - 1 : right;
var counter = []; functionradixSort(arr, maxDigit) { var mod = 10; var dev = 1; for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { for(var j = 0; j < arr.length; j++) { var bucket = parseInt((arr[j] % mod) / dev); if(counter[bucket]==null) { counter[bucket] = []; } counter[bucket].push(arr[j]); } var pos = 0; for(var j = 0; j < counter.length; j++) { var value = null; if(counter[j]!=null) { while ((value = counter[j].shift()) != null) { arr[pos++] = value; } } } } return arr; }
无序数组
调整数组顺序使得奇数位于偶数前面(剑指offer21)
设置两个指针,偶数就删除插入尾部,奇数不做处理
1 2 3 4 5 6 7 8 9 10 11
classSolution: defexchange(self, nums: List[int]) -> List[int]: l=0 h=len(nums) while l < h: if nums[l] % 2 == 0: nums.append(nums.pop(l)) h-=1 else: l+=1 return nums
移动零 283
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
如,输入:[0,1,0,3,12]
输出:[1,3,12,0,0]
注意:不拷贝额外的数组,减少操作次数
1 2 3 4 5 6 7 8 9
classSolution: defmoveZeroes(self, nums: List[int]) -> None: i = 0 for num in nums: if num != 0: nums[i] = num i += 1 for j in xrange(i, len(nums)): nums[j] = 0
两数之和
三数之和(15)
给你一个包含n个整数的数组nums,判断nums中是否存在三个元素,使得这三个整数相加为0
例:输入:nums = [-1,0,1,2,-1,-4]
输出:[-1,-1,2],[-1,0,1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defthreeSum(self, nums: List[int]) -> List[List[int]]: nums.sort() ans = [] seen = set() n = len(nums) for i in range(n): a = nums[i] if a in seen: continue seen.add() d = {} for j in range(i+1,n): b = nums[j] if b in d and (not(ans) or (ans[-1][0]!= a or ans[-1][2] != b)): ans.append((a,-a-b,b)) else: d[-a-b] = 0 return ans
for i in range(n - 2): lo, hi = i + 1, n - 1 # 双指针 while lo < hi: total = nums[i] + nums[lo] + nums[hi] if total == target: return total elif total < target: lo += 1 else: hi -= 1 # 直接根据"最近"的定义取结果 nearest = min(nearest, total, key=lambda x: abs(x - target)) return nearest
两个数组的交集
给定两个数组,编写算法计算他们的交集
例:输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2,2]
1 2 3 4 5 6 7 8 9 10 11 12
classSolution(object): defintersect(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: List[int] """ inter = set(nums1) & set(nums2) l = [] for i in inter: l += [i] * min(nums1.count(i), nums2.count(i)) return l
classSolution: deffourSum(self, nums: List[int], target: int) -> List[List[int]]: nums.sort() n = len(nums) res = [] for i in range(n): if i > 0and nums[i] == nums[i - 1]: continue for k in range(i+1, n): if k > i + 1and nums[k] == nums[k-1]: continue p = k + 1 q = n - 1
while p < q: if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1 elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1 else: res.append([nums[i], nums[k], nums[p], nums[q]]) while p < q and nums[p] == nums[p + 1]: p += 1 while p < q and nums[q] == nums[q - 1]: q -= 1 p += 1 q -= 1 return res
无序整数数组,找出第k大的值215
给定整数数组 nums 和整数 k,请返回数组中第 **k** 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。、
例:输入: [3,2,1,5,6,4] 和 k = 2 输出: 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: deffindKthLargest(self, nums: List[int], k: int) -> int: if len(nums) == 1: return nums[0] mid = int(len(nums) // 2) left, right, mids = [], [], [] for i in range(len(nums)): if nums[i] > nums[mid]: left.append(nums[i]) elif nums[i] < nums[mid]: right.append(nums[i]) else: mids.append(nums[i]) if len(left) >= k: return self.findKthLargest(left, k) elif len(mids) >= k - len(left): return nums[mid] else: return self.findKthLargest(right, k - len(left) - len(mids))
买卖股票的最佳时机1、2、3、4(121,122,123,188,309)
给定数组prices,第i个元素表示股票第i天的价格
需选择在某一天买入,并在某一天卖出,设计一个算法计算获取的最大利润
例:输入:[7,1,5,3,6,4]
输出:5 在第二天买入,第5天卖出,6-1=5
1 2 3 4 5 6 7
classSolution: defmaxProfit(self,prices:List[int])-> int: min_p,max_v = float('inf'),0 for p in prices: min_p = min(min_p,p) max_v = max(max_v,p-min_p) return max_v
classSolution: defmaxProfit(self, prices: List[int]) -> int: ans = 0 for i in range(1, len(prices)): if prices[i] > prices[i-1]: ans += prices[i] - prices[i-1] return ans
dp
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defmaxProfit(self, prices: List[int]) -> int: ifnot prices: return0 n = len(prices) dp = [[0]*2for _ in range(n)] # dp[i][0]表示第i天不持有股票, dp[i][1]表示第i天持有股票 dp[0][0], dp[0][1] = 0, - prices[0] for i in range(1, n): dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]) return dp[n-1][0]
classSolution: defcombinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: ifnot candidates: return [] candidates.sort() n = len(candidates) res = [] defbacktrack(i, tmp_sum, tmp_list): if tmp_sum == target: res.append(tmp_list) return for j in range(i, n): if tmp_sum + candidates[j] > target : break if j > i and candidates[j] == candidates[j-1]:continue backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]]) backtrack(0, 0, []) return res
组合总和3
找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
说明:
所有数字都是正整数。 解集不能包含重复的组合。
输入: k = 3, n = 9 输出: [[1,2,6], [1,3,5], [2,3,4]]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defcombinationSum3(self, k: int, n: int) -> List[List[int]]: res = [] #存放结果集 path = [] #符合条件的结果 deffindallPath(n,k,sum,startIndex): if sum > n: return#剪枝操作 if sum == n and len(path) == k: #如果path.size() == k 但sum != n 直接返回 return res.append(path[:]) for i in range(startIndex,9-(k-len(path))+2): #剪枝操作 path.append(i) sum += i findallPath(n,k,sum,i+1) #注意i+1调整startIndex sum -= i #回溯 path.pop() #回溯 findallPath(n,k,0,1) return res
classSolution: defpermute(self,nums:List[int])->List[List[int]]: res = [] defbacktrack(nums,tmp): ifnot nums: res.append(tmp) return for i in range(len(nums)): backtrack(nums[:i]+nums[i+1],tmp+[nums[i]]) backtrack(nums,[]) return res
classSolution: defsubsetsWithDup(self, nums: List[int]) -> List[List[int]]: res = [] #存放符合条件结果的集合 path = [] #用来存放符合条件结果 defbacktrack(nums,startIndex): res.append(path[:]) for i in range(startIndex,len(nums)): if i > startIndex and nums[i] == nums[i - 1]: #我们要对同一树层使用过的元素进行跳过 continue path.append(nums[i]) backtrack(nums,i+1) #递归 path.pop() #回溯 nums = sorted(nums) #去重需要排序 backtrack(nums,0) return res
移除元素(27)
给出一个数组和一个值val,你需要原地移除所有数值等于val的元素,并返回移除后数组的长度
例:输入:nums = [3,2,2,3] val= 3
输出:2,nums = [2,2]
快慢指针
1 2 3 4 5 6 7 8
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: i = 0 for j in range(len(nums)): if nums[j] != val: nums[i] = nums[j] i += 1 return i
classSolution: deflengthOfLIS(self, nums: List[int]) -> int: n = len(nums) dp = [1for _ in range(n)] for i in range(1, n): for j in range(i): if nums[j] < nums[i]: dp[i] = max(dp[i], dp[j] + 1) return max(dp)
classSolution: defsingleNumber(self, nums: List[int]) -> int: nums.sort() for i in range(0,len(nums)-3,3): if nums[i]!=nums[i+1]: return nums[i] return nums[-1]
缺失的第一个正数(41)
给你一个未排序的整数数组nums,请你找出其中没有出现的最小的正整数
例:输入:[1,2,0]
输出:4
1 2 3 4 5 6
classSolutioon: deffirstMissingPositive(self,nums:List[int])-> int: nums = set(nums) for j in range(1, 2 ** 31 - 1): if j notin nums: return j
颜色分类(75)
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
classSolution: deflargestRectangleArea(self, heights: List[int]) -> int: ans, s, hs = 0, [0], [0, *heights, 0] for i, h in enumerate(hs): while hs[s[-1]] > h: ans = max(ans, (i - s[-2] - 1) * hs[s.pop()]) s.append(i) return ans
长度最小的子数组(209)
给定一个含有n个正整数和一个正整数target
找出该数组中满足其和大于target的长度最小的连续子数组,并返回其长度
例:nums=[2,3,1,2,4,3], target=7
输出:2
1 2 3 4 5 6 7 8 9 10
classSolution: defminSubArrayLen(self, target:int,nums: List[int])-> int: i, ans = 0, len(A) + 1 for j in range(len(A)): s -= A[j] while s <= 0: ans = min(ans,j-i+1) s += A[i] i += 1 return ans % (len(A)+1)
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。
例:输入:nums = [1,2,3,1], k = 3
输出:true
输入:nums = [1,2,3,1,2,3], k = 2
输出:false
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defcontainsNearbyDuplicate(self, nums: List[int], k: int) -> bool: nums_len = len(nums) if nums_len <= 1: returnFalse nums_dict = {} for i in range(nums_len): if nums[i] in nums_dict: if i-nums_dict[nums[i]] <= k: returnTrue nums_dict[nums[i]] = i returnFalse
存在重复元素3(220)
给你一个整数数组 nums 和两个整数 k 和 t 。请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] - nums[j]) <= t ,同时又满足 abs(i - j) <= k 。
如果存在则返回 true,不存在返回 false。
例:输入:nums = [1,2,3,1], k = 3, t = 0
输出:true
输入:nums = [1,5,9,1,5,9], k = 2, t = 3
输出:false
1 2 3 4 5 6 7 8 9 10 11
classSolution: defcontainsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool: ls = [[nums[i], i] for i in range(len(nums))] ls.sort(key=lambda x: x[0]) for i in range(len(nums)): for j in range(i + 1, len(nums)): if ls[j][0] - ls[i][0] > t: break if abs(ls[j][1] - ls[i][1]) <= k: returnTrue returnFalse
寻找重复数字287
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。
你设计的解决方案必须不修改数组 nums 且只用常量级 O(1) 的额外空间。
例:输入:nums = [1,3,4,2,2] 输出:2
1 2 3 4 5 6 7 8 9 10
classSolution: deffindDuplicate(self, nums: List[int]) -> int: lo, hi = 1, len(nums)-1 while lo < hi: mid = (lo + hi) // 2 if sum(i<=mid for i in nums) <= mid: lo = mid + 1 else: hi = mid return lo
数组中重复的数据(442)
给定一个整数数组a,其中有些元素出现了两次而有些元素出现了一次,找出所有出现两次的元素
输入:[4,3,2,7,8,2,3,1]
输出:[2,3]
1 2 3 4 5 6 7 8 9
classSolution: deffindDuplicates(self, nums:List[int])-> List[int]: res = [] for x in nums: if nums[abs(x-1)] < 0: res.append(abs(x)) else: nums[abs(x)-1] *= -1 return res
classSolution: deffindPeakElement(self, nums: List[int]) -> int: lo, hi = 0, len(nums)-1 while lo < hi: mid = (lo+hi) // 2 mid2 = mid + 1 if nums[mid] < nums[mid2]: lo = mid2 else: hi = mid return lo
多数元素(169)
波义尔摩尔投票算法
1 2 3 4 5 6 7 8
defmajorityElement(self, nums): count = 0 candidate = None for num in nums: if count == 0: candidate = num count += (1if num == candidate else-1) return candidate
求众数(229)
给定一个大小为n的整数组,找出其中所有出现超过n/3次的元素
输入:[3,2,3]
输出:[3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
classSolution: defmajorityElement(self, nums:List[int]) -> Lisr[int]: count1, count2, candidate1, candidate2 = 0,0,0,1 for n in nums: if n == candidate1: count1 += 1 elif n == candidate2: count2 += 1 elif count1 == 0: candidate1, count1 = n,1 elif count2 == 0: candidate2, count2 = n,1 else: count1, count2 = count1 - 1,count2 - 1 return [n for n in (candidate1,candidate2) if nums.count(n) > len(nums) // 3]
l, r = 0, len(nums) - 1 while l < r: mid = l + (r - l) // 2# 向左取整 if nums[mid] < target: # 首先考虑一定不存在解的区间,则有+1(或者-1) l = mid + 1 else: r = mid ifnot nums or nums[l] != target: # 用例中有nums = [] 的情况 return res res[0] = l l, r = r, len(nums) - 1 while l < r: mid = l + (r - l + 1) // 2# 向右取整 if nums[mid] > target: r = mid - 1 else: l = mid res[1] = r return res
classSolution: defmerge(self,intervals:List[List[int]])->List[List[int]]: if intervals == []: return [] intervals.sort(key = lambda x:x[0]) ##前一个合并区间 pre = intervals[0] res = [] for i in range(1,len(intervals)): if intervals[i][0] <= pre[1]: ##合并,更新pre结束位置 if intervals[i][1] > pre[1]: pre[1] = intervals[i][1] else res.append(pre) pre = intervals[i] ##最后一个没有加进去 res.append(pre) return res
merge = [intervals[0]] for i in range(1, len(intervals)): mergeleft = merge[-1][0] mergeright = merge[-1][1] interleft = intervals[i][0] interright = intervals[i][1] if interleft > mergeright: merge.append(intervals[i]) else: merge[-1][1] = max(mergeright, interright) return merge
删除有序数组的重复项(26)
删除有序数组中重复的元素,在原数组上进行操作,
1 2 3 4 5 6 7 8 9
defremoveDuplicates(nums): ifnot nums: return0 index = 1 for i in range(len(nums)-1): if nums[i] != nums[i+1]: nums[index] = nums[i+1] index +=1 return index
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defmerge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: i, j, k = m-1, n-1, m+n-1 while i >=0and j >= 0: if nums1[i] > nums2[j]: nums1[k] = nums1[i] i -= 1 else: nums1[k] = nums2[j] j -= 1 k -= 1 while j >= 0: nums1[k] = nums2[j] j -= 1 k -= 1
汇总区间(228)
给定一个无重复元素的有序整数数组,返回恰好覆盖数组中所有数组的最小有序区间范围列表,
例:nums = [0,1,2,4,5,7]
输出:[“0->2”,”4->5”,”7”]
nums = [0,2,3,4,6,8,9]
输出:[“0”,”2->4”,”6”,”8->9”]
1 2 3 4 5 6 7 8 9 10 11
classSolution: defsummaryRange(self, nums: List[int]) -> List[str]: li = [] i = 0 while i < len(nums): j = i + 1; while j < len(nums) and nums[j] == nums[i] + j - i: j += 1 li.append(str(nums[i]) if i == j-1else str(nums[i]) + '->' + str(nums[j-1])) i = j return li
classSolution: deffindRightInterval(self, intervals: List[List[int]]) -> List[int]: n = len(intervals) res = [-1] * n dic = {} for i, v in enumerate(intervals): dic[v[0]] = i start = sorted(dic.keys()) for i, v in enumerate(intervals): l, r = 0, n - 1 while l <= r: mid = (l + r) >> 1 if v[1] > start[mid]: l = mid + 1 else: r = mid - 1 if l < n: res[i] = dic[start[l]]
return res
和为s的连续正数序列(剑指offer57)
输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
例:输入:target = 9
输出:[[2,3,4],[4,5]]
双指针滑动窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: deffindContinuousSequence(self, target: int) -> List[List[int]]: n = target//2+1 nums = list(range(1,n+1)) left,right = 0,0 sums,res = 0,[] while right<len(nums): sums+=nums[right] right+=1 while sums>=target: if sums==target: res.append(nums[left:right]) sums-=nums[left] left+=1 return res
classSolution: defmaximalRectangle(self, matrix: List[List[str]]) -> int: if len(matrix) == 0: return0 res = 0 m, n = len(matrix), len(matrix[0]) heights = [0] * n for i in range(m): for j in range(n): if matrix[i][j] == '0': heights[j] = 0 else: heights[j] = heights[j] + 1 res = max(res, self.largestRectangleArea(heights)) return res deflargestRectangleArea(self, heights): heights.append(0) stack = [] res = 0 for i in range(len(heights)): while stack and heights[i] < heights[stack[-1]]: s = stack.pop() res = max(res, heights[s] * ((i - stack[-1] - 1) if stack else i)) stack.append(i) return res
单词搜索(79)
给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
例:输入:board = [[“A”,”B”,”C”,”E”],[“S”,”F”,”C”,”S”],[“A”,”D”,”E”,”E”]], word = “ABCCED”
输出:true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution: defexist(self, board: List[List[str]], word: str) -> bool: l,w = len(board),len(board[0]) l_word = len(word) defdfs(a,b,index,hel): if a<0or b<0or a>=l or b>=w or board[a][b]!=word[index] or (a,b) in hel: returnFalse elif board[a][b]==word[index] and index==len(word)-1: returnTrue return dfs(a+1,b,index+1,hel+[(a,b)]) or dfs(a-1,b,index+1,hel+[(a,b)]) or dfs(a,b+1,index+1,hel+[(a,b)]) or dfs(a,b-1,index+1,hel+[(a,b)]) for i in range(l): for j in range(w): if board[i][j] == word[0]: if dfs(i,j,0,[]): returnTrue returnFalse
classSolution: defhelper(self,grid,i,j): if i<0or j<0or i>=len(grid) or j>=len(grid[0]) or grid[i][j]==0: return0 grid[i][j]=0 count=1 tmp = [[1,0],[-1,0],[0,1],[0,-1]] for x,y in tmp: dx = x+i dy = y+j count+=self.helper(grid,dx,dy) return count defmaxAreaOfIsland(self, grid: List[List[int]]) -> int: res = 0 for i in range(len(grid)): for j in range(len(grid[0])): if grid[i][j]==1: tmp = self.helper(grid,i,j) res = max(tmp,res) return res
三角形路径之和(120)
给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
classSolution: defminimumTotal(self, triangle: List[List[int]]) -> int: #自底向上 dp = triangle m = len(triangle) for i in range(m-1,-1,-1): if i<m-1: for j in range(len(triangle[i])): dp[i][j] += min(dp[i+1][j],dp[i+1][j+1]) return dp[0][0]
classSolution: defminimumTotal(self, triangle: List[List[int]]) -> int: #自底向上 dp = triangle[-1] m = len(triangle) for i in range(m-1,-1,-1): if i<m-1: for j in range(len(triangle[i])): dp[j] = min(dp[j],dp[j+1]) + triangle[i][j] return dp[0]
classSolution: defspiralOrder(self, matrix: List[List[int]]) -> List[int]: ret = [] if matrix == []: return ret ret.extend(matrix[0]) # 上侧 new = [reversed(i) for i in matrix[1:]] if new == []: return ret r = self.spiralOrder([i for i in zip(*new)]) ret.extend(r) return ret
顺时针生成数组(59)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
defgenerateMatrix(self,n: int) -> List[List[int]]: ans = [[0]*n for _ in range(n)] op = itertools.cycle([(0,1),(1,0),(0,-1),(-1,0)]) d = next(op) x,y = [0,0] for k = range(1,n**2+1): ans[x][y] = k i,j = x+d[0], y+d[1] ifnot0<= i < n ornot0<=j<n or ans[i][j]: d = next(op) x,y = x+d[0], y+d[1] else: x,y = i,j return ans
有序矩阵中第 K 小的元素378
给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。 请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。
classSolution: defkthSmallest(self, matrix: List[List[int]], k: int) -> int: lo, hi = matrix[0][0], matrix[-1][-1] while lo < hi: mid = (lo + hi) // 2 if sum(bisect.bisect(row, mid) for row in matrix) < k: lo = mid + 1 else: hi = mid return lo
classSolution: defsearch(self,nums,target): lo,hi = 0,len(nums)-1 while lo < hi: mid = (lo + hi)//2 if(nums[0] > target) ^ (nums[0]>nums[mid]) ^ (target>nums[mid]): lo = mid + 1 else hi = mid return lo if lo == hi and target == nums[lo] else-1