[Swift]LeetCode373. 查找和最小的K对数字 | Find K Pairs with Smallest Sums
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/10278047.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
Define a pair (u,v) which consists of one element from the first array and one element from the second array.
Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
Example 1:
Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 Output: [[1,2],[1,4],[1,6]] Explanation: The first 3 pairs are returned from the sequence: [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
Example 2:
Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2 Output: [1,1],[1,1] Explanation: The first 2 pairs are returned from the sequence: [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
Example 3:
Input: nums1 = [1,2], nums2 = [3], k = 3 Output: [1,3],[2,3] Explanation: All possible pairs are returned from the sequence: [1,3],[2,3]
给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。
找到和最小的 k 对数字 (u1,v1), (u2,v2) ... (uk,vk)。
示例 1:
输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3 输出: [1,2],[1,4],[1,6] 解释: 返回序列中的前 3 对数:[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
示例 2:
输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2 输出: [1,1],[1,1] 解释: 返回序列中的前 2 对数:[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
示例 3:
输入: nums1 = [1,2], nums2 = [3], k = 3 输出: [1,3],[2,3] 解释: 也可能序列中所有的数对都被返回:[1,3],[2,3]
52ms
1 class Solution { 2 //Use priority queue 3 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 4 guard k > 0, nums1.count > 0, nums2.count > 0 else { 5 return [[Int]]() 6 } 7 8 let pq = PriorityQueue<Pair>(priorityFunction:{(p1, p2) in 9 return p1.sum < p2.sum 10 }) 11 12 var result = [[Int]]() 13 14 for j in 0..<nums2.count { 15 let pair = Pair(i:0, j:j, sum:nums1[0] + nums2[j]) 16 pq.enqueue(element:pair) 17 } 18 19 20 21 22 for i in 0..<min(k, nums1.count * nums2.count) { 23 if let cur = pq.dequeue() { 24 result.append([nums1[cur.i], nums2[cur.j]]) 25 if cur.i == nums1.count - 1 { 26 continue 27 } 28 let pair = Pair(i:cur.i + 1, j:cur.j, sum:nums1[cur.i + 1] + nums2[cur.j]) 29 pq.enqueue(element:pair) 30 } 31 } 32 33 return result 34 } 35 } 36 37 class Pair { 38 let i: Int 39 let j: Int 40 let sum: Int 41 init(i:Int, j:Int, sum:Int) { 42 self.i = i 43 self.j = j 44 self.sum = sum 45 } 46 } 47 48 49 public class PriorityQueue<Element> { 50 var elements: [Element] 51 var priorityFunction: (Element, Element) -> Bool 52 var count: Int { return elements.count } 53 54 init(priorityFunction:@escaping (Element, Element) -> Bool) { 55 self.elements = [Element]() 56 self.priorityFunction = priorityFunction 57 } 58 59 func isHigherPriority(at index:Int,than secondIndex:Int) -> Bool { 60 return self.priorityFunction(elements[index], elements[secondIndex]) 61 } 62 63 func enqueue(element:Element) { 64 elements.append(element) 65 siftUp(index: elements.count - 1) 66 } 67 68 func dequeue() -> Element? { 69 if elements.count == 0 { 70 return nil 71 } 72 73 elements.swapAt(0, elements.count - 1) 74 let element = elements.removeLast() 75 siftDown(index: 0) 76 return element 77 } 78 79 func peek() -> Element? { 80 return elements.last 81 } 82 83 func siftUp(index:Int) { 84 if index == 0 { 85 return 86 } 87 88 let parent = parentIndex(for: index) 89 if isHigherPriority(at: index, than: parent) { 90 elements.swapAt(index, parent) 91 siftUp(index: parent) 92 } 93 } 94 95 func siftDown(index:Int) { 96 var highIndex = index 97 let leftIndex = leftChildIndex(for: index) 98 let rightIndex = rightChildIndex(for: index) 99 if leftIndex < count && isHigherPriority(at: leftIndex, than: index) { 100 highIndex = leftIndex 101 } 102 if rightIndex < count && isHigherPriority(at: rightIndex, than: highIndex) { 103 highIndex = rightIndex 104 } 105 if highIndex == index { 106 return 107 } else { 108 elements.swapAt(highIndex, index) 109 siftDown(index: highIndex) 110 } 111 } 112 113 func parentIndex(for index:Int) -> Int { 114 return (index - 1)/2 115 } 116 117 func leftChildIndex(for index:Int) -> Int { 118 return index * 2 + 1 119 } 120 121 func rightChildIndex(for index:Int) -> Int { 122 return index * 2 + 2 123 } 124 }
240ms
1 class Solution { 2 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 3 4 var res = [[Int]]() 5 let n1 = nums1.count 6 let n2 = nums2.count 7 guard n1 > 0 && n2 > 0 else { 8 return res 9 } 10 var heap = Heap<Node>(type:. min) 11 var visited = [[Bool]](repeating: [Bool](repeating: false, count: n2), count:n1) 12 13 heap.add(Node(nums1[0] + nums2[0], [nums1[0], nums2[0]], 0, 0)) 14 visited[0][0] = true 15 var count = k 16 17 18 while count > 0 && heap.count > 0{ 19 var curr = heap.remove()! 20 res.append(curr.arr) 21 count -= 1 22 if curr.x + 1 < n1 && !visited[curr.x + 1][curr.y]{ 23 let i = nums1[curr.x + 1] 24 let j = nums2[curr.y] 25 heap.add(Node(i + j, [i, j], curr.x + 1 , curr.y)) 26 visited[curr.x + 1][curr.y] = true 27 } 28 if curr.y + 1 < n2 && !visited[curr.x][curr.y + 1]{ 29 let i = nums1[curr.x] 30 let j = nums2[curr.y + 1] 31 heap.add(Node(i + j, [i, j], curr.x, curr.y + 1)) 32 visited[curr.x][curr.y + 1] = true 33 } 34 } 35 return res 36 } 37 38 39 struct Node: Comparable{ 40 var value : Int 41 var x:Int 42 var y:Int 43 var arr : [Int] 44 init(_ n: Int, _ array:[Int],_ x:Int,_ y:Int){ 45 value = n 46 arr = array 47 self.x = x 48 self.y = y 49 } 50 51 static func < (ls:Node ,rs: Node) -> Bool{ 52 return ls.value < rs.value 53 } 54 static func == (ls:Node ,rs: Node) -> Bool{ 55 return ls.value == rs.value 56 } 57 } 58 59 60 struct Heap<E: Comparable> { 61 enum HeapType { case max, min } 62 63 // an array representing the binary tree 64 var tree = [E]() 65 66 // indicating if this heap is a max heap or min heap 67 let type: HeapType 68 69 var count: Int { 70 return tree.count 71 } 72 73 init(type: HeapType) { 74 self.type = type 75 } 76 77 mutating func add(_ element: E) { 78 tree.append(element) 79 var child = tree.count - 1 80 var parent = (child - 1) / 2 81 while child > 0 && !satify(tree[parent], tree[child]) { 82 tree.swapAt(parent, child) 83 child = parent 84 parent = (child - 1) / 2 85 } 86 assert(isHeap(0), "borken heap: \(tree)") 87 } 88 89 mutating func remove() -> E? { 90 let rev = tree.first 91 if tree.count > 0 { 92 tree.swapAt(0, tree.count - 1) 93 tree.removeLast() 94 heapify(0) 95 } 96 assert(isHeap(0), "borken heap: \(tree)") 97 return rev 98 } 99 100 func peek() -> E? { 101 return tree.first 102 } 103 104 mutating private func heapify(_ rootIndex: Int) { 105 let count = tree.count 106 let leftChild = 2 * rootIndex + 1 107 let rightChild = 2 * rootIndex + 2 108 109 // no children 110 if leftChild >= count { return } 111 112 let targetChild = (rightChild >= count || satify(tree[leftChild], tree[rightChild])) ? leftChild : rightChild 113 if (!satify(tree[rootIndex], tree[targetChild])) { 114 tree.swapAt(rootIndex, targetChild) 115 heapify(targetChild) 116 } 117 } 118 119 private func satify(_ lhs: E, _ rhs: E) -> Bool { 120 return (self.type == .min) ? (lhs <= rhs) : (lhs >= rhs) 121 } 122 123 // debugging helper methods 124 private func isHeap(_ rootIndex: Int) -> Bool { 125 let leftChild = 2 * rootIndex + 1 126 let rightChild = 2 * rootIndex + 2 127 var valid = true 128 if leftChild < tree.count { 129 valid = satify(tree[rootIndex], tree[leftChild]) && isHeap(leftChild) 130 } 131 132 if !valid { return false } 133 134 if rightChild < tree.count { 135 valid = satify(tree[rootIndex], tree[rightChild]) && isHeap(rightChild) 136 } 137 return valid 138 } 139 } 140 }
844ms
1 class Solution { 2 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 3 4 guard nums1.count > 0 && nums2.count > 0 else { 5 return [] 6 } 7 8 var heap = PairHeap() 9 var result = [[Int]]() 10 var set = [(Int,Int)]() 11 12 heap.addPair((0,0,nums1[0]+nums2[0])) 13 for _ in 1...k { 14 15 if heap.pairs.count > 0 { 16 let cur = heap.poll() 17 18 result.append([nums1[cur.0],nums2[cur.1]]) 19 20 var i = cur.0 + 1 21 var j = cur.1 22 23 24 if i < nums1.count && !(set.contains(where: { $0 == (i,j) })){ //if used hashmap, it will update eg i = 1 again n again 25 heap.addPair((i,j,nums1[i]+nums2[j])) 26 27 set.append((i,j)) 28 } 29 30 i = cur.0 31 j = cur.1 + 1 32 33 if j < nums2.count && !(set.contains(where: { $0 == (i,j) })){ 34 heap.addPair((i,j,nums1[i]+nums2[j])) 35 set.append((i,j)) 36 37 } 38 //dump(heap.pairs) 39 } 40 //print(set) 41 } 42 43 return result 44 } 45 46 struct PairHeap { 47 48 var pairs: [(Int,Int,Int)] = [] 49 50 func getLeftChildIndex(_ parentIndex: Int) -> Int{ 51 return 2*parentIndex + 1 52 } 53 54 func getRightChildIndex(_ parentIndex: Int) -> Int{ 55 return 2*parentIndex + 2 56 } 57 58 func getParentIndex(_ childIndex: Int) -> Int{ 59 return (childIndex-1)/2 60 } 61 62 // Return Item From Heap 63 func getLeftChild(_ parenIndex: Int) -> (Int,Int,Int) { 64 return pairs[getLeftChildIndex(parenIndex)] 65 } 66 67 func getRightChild(_ parenIndex: Int) -> (Int,Int,Int) { 68 return pairs[getRightChildIndex(parenIndex)] 69 } 70 71 func getParent(_ childIndex: Int) -> (Int,Int,Int) { 72 return pairs[getParentIndex(childIndex)] 73 } 74 75 // Boolean Check 76 private func hasLeftChild(_ index: Int) -> Bool { 77 return getLeftChildIndex(index) < pairs.count 78 } 79 private func hasRightChild(_ index: Int) -> Bool { 80 return getRightChildIndex(index) < pairs.count 81 } 82 private func hasParent(_ index: Int) -> Bool { 83 return getParentIndex(index) >= 0 84 } 85 86 mutating func addPair(_ item : (Int,Int,Int)) { 87 pairs.append(item) 88 heapifyUp() 89 } 90 91 mutating public func poll() -> (Int,Int,Int) { 92 if pairs.count > 0 { 93 let item = pairs[0] 94 pairs[0] = pairs[pairs.count - 1] 95 pairs.removeLast() 96 heapifyDown() 97 return item 98 99 } else { 100 fatalError() 101 } 102 } 103 104 mutating func heapifyDown() { 105 var index = 0 106 107 while hasLeftChild(index) { 108 var child = getLeftChildIndex(index) 109 if hasRightChild(index) && getRightChild(index).2 < pairs[child].2 { 110 child = getRightChildIndex(index) 111 } 112 113 if pairs[child].2 > pairs[index].2 { 114 break 115 } else { 116 pairs.swapAt(index, child) 117 } 118 index = child 119 } 120 121 } 122 123 mutating func heapifyUp() { 124 var index = pairs.count - 1 125 while hasParent(index) && getParent(index).2 > pairs[index].2 { 126 pairs.swapAt(index, getParentIndex(index)) 127 index = getParentIndex(index) 128 } 129 } 130 } 131 }
884ms
1 class Solution { 2 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 3 if nums1.count == 0 || nums2.count == 0 { 4 return [[Int]]() 5 } 6 7 var rev = [[Int]]() 8 var inHeap = Array(repeating: Array(repeating: false, count: nums2.count), count: nums1.count) 9 var heap = Heap<Node>(type: .min) 10 11 for i in 0 ..< nums2.count { 12 let n = Node(pair: [nums1[0], nums2[i]], r: 0, c: i) 13 heap.add(n) 14 } 15 16 while rev.count < k && heap.count > 0 { 17 let n = heap.remove()! 18 rev.append(n.pair) 19 20 if n.r + 1 < nums1.count { 21 heap.add(Node(pair: [nums1[n.r + 1], nums2[n.c]], r: n.r + 1, c: n.c)) 22 } 23 } 24 25 return rev 26 } 27 } 28 29 struct Node: Comparable { 30 let pair: [Int] 31 let r: Int 32 let c: Int 33 34 static func == (lhs: Node, rhs: Node) -> Bool { 35 return (lhs.pair[0] + lhs.pair[1]) == (rhs.pair[0] + rhs.pair[1]) 36 } 37 38 static func < (lhs: Node, rhs: Node) -> Bool { 39 return (lhs.pair[0] + lhs.pair[1]) < (rhs.pair[0] + rhs.pair[1]) 40 } 41 } 42 43 struct Heap<E: Comparable> { 44 enum HeapType { case max, min } 45 46 // an array representing the binary tree 47 var tree = [E]() 48 49 // indicating if this heap is a max heap or min heap 50 let type: HeapType 51 52 var count: Int { 53 return tree.count 54 } 55 56 init(type: HeapType) { 57 self.type = type 58 } 59 60 mutating func add(_ element: E) { 61 tree.append(element) 62 var child = tree.count - 1 63 var parent = (child - 1) / 2 64 while child > 0 && !satify(tree[parent], tree[child]) { 65 tree.swapAt(parent, child) 66 child = parent 67 parent = (child - 1) / 2 68 } 69 assert(isHeap(0), "borken heap: \(tree)") 70 } 71 72 mutating func remove() -> E? { 73 let rev = tree.first 74 if tree.count > 0 { 75 tree.swapAt(0, tree.count - 1) 76 tree.removeLast() 77 heapify(0) 78 } 79 assert(isHeap(0), "borken heap: \(tree)") 80 return rev 81 } 82 83 func peek() -> E? { 84 return tree.first 85 } 86 87 mutating private func heapify(_ rootIndex: Int) { 88 let count = tree.count 89 let leftChild = 2 * rootIndex + 1 90 let rightChild = 2 * rootIndex + 2 91 92 // no children 93 if leftChild >= count { return } 94 95 let targetChild = (rightChild >= count || satify(tree[leftChild], tree[rightChild])) ? leftChild : rightChild 96 if (!satify(tree[rootIndex], tree[targetChild])) { 97 tree.swapAt(rootIndex, targetChild) 98 heapify(targetChild) 99 } 100 } 101 102 private func satify(_ lhs: E, _ rhs: E) -> Bool { 103 return (self.type == .min) ? (lhs <= rhs) : (lhs >= rhs) 104 } 105 106 // debugging helper methods 107 private func isHeap(_ rootIndex: Int) -> Bool { 108 let leftChild = 2 * rootIndex + 1 109 let rightChild = 2 * rootIndex + 2 110 var valid = true 111 if leftChild < tree.count { 112 valid = satify(tree[rootIndex], tree[leftChild]) && isHeap(leftChild) 113 } 114 115 if !valid { return false } 116 117 if rightChild < tree.count { 118 valid = satify(tree[rootIndex], tree[rightChild]) && isHeap(rightChild) 119 } 120 return valid 121 } 122 }
1512ms
1 class Solution { 2 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 3 4 var res = [[Int]]() 5 for i in 0..<min(k, nums1.count) { 6 for j in 0..<min(k, nums2.count) { 7 res.append([nums1[i], nums2[j]]) 8 } 9 } 10 res.sort{$0[0]+$0[1] < $1[0]+$1[1]} 11 return Array(res.prefix(k)) 12 } 13 }
2516ms
1 class Solution { 2 func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] { 3 var res:[[Int]] = [[Int]]() 4 let number1:Int = min(nums1.count, k) 5 let number2:Int = min(nums2.count, k) 6 for i in 0..<number1 7 { 8 for j in 0..<number2 9 { 10 res.append([nums1[i], nums2[j]]) 11 } 12 } 13 res.sort(by:{(a:[Int],b:[Int]) -> Bool in return a[0] + a[1] < b[0] + b[1] }) 14 if res.count > k 15 { 16 var ans:[[Int]] = [[Int]]() 17 for i in 0..<k 18 { 19 ans.append(res[i]) 20 } 21 return ans 22 } 23 else 24 { 25 return res 26 } 27 } 28 }
转载于:https://www.cnblogs.com/strengthen/p/10278047.html
[Swift]LeetCode373. 查找和最小的K对数字 | Find K Pairs with Smallest Sums相关推荐
- 373. Find K Pairs with Smallest Sums 找出求和和最小的k组数
[抄题]: You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. D ...
- 373. Find K Pairs with Smallest Sums (java,优先队列)
题目: You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k. Def ...
- leetcode 373. Find K Pairs with Smallest Sums | 373. 查找和最小的K对数字(小根堆)
题目 https://leetcode.com/problems/find-k-pairs-with-smallest-sums/ 题解 本来以为是个双指针+贪心,但是后来发现如果用双指针的话,指针并 ...
- LeetCode Find K Pairs with Smallest Sums(大根堆、小根堆)
问题:给出两个有序数组nums1,nums2,要求从两个数组中各取一个数,组成一对数据,输出和最小的k对 思路:方法1使用大根堆,当堆中元素个数小于k时,直接入堆.否则比较当前数据对与堆顶的元素,如果 ...
- Java实现 LeetCode 373 查找和最小的K对数字
373. 查找和最小的K对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找 ...
- ⭐算法入门⭐《堆》中等03 —— LeetCode 373. 查找和最小的K对数字
文章目录 一.题目 1.题目描述 2.基础框架 3.原题链接 二.解题报告 1.思路分析 2.时间复杂度 3.代码详解 三.本题小知识 四.加群须知 一.题目 1.题目描述 给定两个以升序排列的整 ...
- LeetCode 373. 查找和最小的K对数字(自定义优先队列BFS)
1. 题目 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找到和最小的 k 对数 ...
- 【LeetCode笔记 - 每日一题】373. 查找和最小的 K 对数字(Java、堆、优先队列)
文章目录 题目描述 思路 && 代码 题目描述 几天没打题,感觉脑子都是一团浆糊.... 升序:肯定得用这条件来优化复杂度 数对:用 int[2] 来表示 思路 && ...
- 给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列组成⼀个新的正整数,求组成的新数最小的删数方案(O((n-k)logk)优化)
问题描述 给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列组成⼀个新的正整数.对于给定的n和k,设计⼀个算法,找出剩下数字组成的新数最少的删数方案. 这一道题来自zyq老师的算法分析与 ...
最新文章
- 【 Verilog HDL 】正确的变量访问思路
- 一文简单弄懂tensorflow_【TensorFlow】一文弄懂CNN中的padding参数
- delphi VCL研究之消息分发机制(转)
- 20应用统计考研复试要点(part12)--应用多元分析
- kickstart安装
- python基础学习笔记——异常处理
- linux open函数解释,linux之open函数解析
- .bash_profile .bashrc profile 文件的作用的执行顺序
- 爬取糗事百科1到5页的图片并下载到本地
- 软件工程——毕业论文管理系统
- 如何根据一张照片判断出女孩住在几层楼?
- 水晶头/双绞线的线序
- 计算机id换系统会变吗,小雷问答丨手机恢复出厂设置后会变成最原始的系统吗?...
- 解读随着教育改革的深入steam教育
- netstat查看网络状态(windows)
- Kanzi入门学习(一)
- WIN10 Outlook 2013 pst/ost邮件数据文件迁移
- 一次惨痛的线下机房上云的经历
- 用浏览器访问云服务器文件,浏览器访问云服务器文件
- 【服务器数据恢复】EMC存储Zfs文件系统下raid5数据恢复案例
热门文章
- redis延迟消息队列不准时php,Redis实现延迟消息队列
- 骂骂咧咧的 fastreport 数据隔行换色
- 网络营销专员浅析企业网站网络营销的多个优势!
- 浅析在网站软文内容中是如何做好关键词优化的?
- linux 下的dd,Linux中的dd命令
- python请求url非阻塞_Tornado请求中的非阻塞/异步URL获取
- linux cp命令逻辑,Linux-CP命令
- java axis2 jar_Java axis2.jar包详解及缺少jar包错误分析
- 系统运维包括哪些内容_智能养老系统包括哪些?养老管理系统内容详解
- 大规模异常滥用检测:基于局部敏感哈希算法——来自Uber Engineering的实践