Skip to content

Commit 0a91592

Browse files
committed
regular leetcode
1 parent 310febc commit 0a91592

File tree

1 file changed

+79
-7
lines changed

1 file changed

+79
-7
lines changed

215._kth_largest_element_in_an_array.md

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33

44

5+
<https://leetcode.com/problems/kth-largest-element-in-an-array/>
6+
57

68
### 想法
79

@@ -11,12 +13,25 @@
1113

1214
#### O(nlgn)
1315

14-
看这段代码,简直是Pythonize的代表作.
16+
看这段Swift代码,简直是Pythonize的代表作.
1517

1618
如果需要reverse排序可`reversed = names.sort(>)`
1719

1820
[sort参见](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html)
1921

22+
因为nums是不可变,所以其实这样也蛮浪费的,但是可以AC
23+
24+
```swift
25+
class Solution {
26+
func findKthLargest(_ nums: [Int], _ k: Int) -> Int {
27+
var sortedNums = nums.sorted()
28+
return sortedNums[nums.count - k]
29+
}
30+
}
31+
```
32+
33+
34+
2035

2136
#### O(n) + O(klgn)
2237

@@ -67,10 +82,13 @@ class Solution(object):
6782

6883

6984

85+
#### O(n)
86+
87+
发现这个O(n) 是average case, worst case 是 O(n^2)
88+
89+
CLRS ch9.3 可以找到, wikipedia可以找到: https://en.wikipedia.org/wiki/Quickselect
7090

71-
#### O(n)
7291

73-
CLRS ch9.3 可以找到
7492

7593

7694
[最佳资源在此处](https://github.com/raywenderlich/swift-algorithm-club/tree/master/Kth%20Largest%20Element)
@@ -81,7 +99,7 @@ CLRS ch9.3 可以找到
8199
注意写的是第k小的,然后这里是求第k大的
82100
<https://rosettacode.org/wiki/Quickselect_algorithm#Python>
83101

84-
```
102+
```python
85103
class Solution(object):
86104
def findKthLargest(self, nums, k):
87105
"""
@@ -120,7 +138,54 @@ class Solution(object):
120138
```
121139

122140

123-
时间复杂度是O(n),CLRS里面有出现这个算法和证明
141+
142+
对照wikipedia写出来的:
143+
144+
```python
145+
class Solution(object):
146+
def findKthLargest(self, nums, k):
147+
"""
148+
:type nums: List[int]
149+
:type k: int
150+
:rtype: int
151+
"""
152+
def partition(lst, left, right, pivotIndex):
153+
pivotValue = lst[pivotIndex]
154+
lst[pivotIndex], lst[right] = lst[right], lst[pivotIndex]
155+
storeIndex = left
156+
for i in range(left, right):
157+
if lst[i] < pivotValue:
158+
lst[storeIndex], lst[i] = lst[i], lst[storeIndex]
159+
storeIndex += 1
160+
lst[right], lst[storeIndex] = lst[storeIndex], lst[right]
161+
return storeIndex
162+
163+
# kth smallest
164+
def select(lst, left, right, k):
165+
if left == right:
166+
return lst[left]
167+
pivotIndex = left
168+
pivotIndex = partition(lst, left, right, pivotIndex)
169+
170+
if k == pivotIndex:
171+
return lst[k]
172+
elif k < pivotIndex:
173+
return select(lst, left, pivotIndex - 1, k)
174+
else:
175+
return select(lst, pivotIndex + 1, right, k)
176+
n = len(nums)
177+
return select(nums, 0, n - 1, n - k)
178+
```
179+
180+
181+
182+
跟上面的方法区别也不大,一个recursion, 一个for loop,注意下面跟初等算法解释的对比,因为这里我们并没有去减小lst,所以我们的k是不用变化的。
183+
184+
185+
186+
187+
188+
124189

125190

126191
摘自初等算法的解释,我觉得解释的非常棒
@@ -135,7 +200,7 @@ class Solution(object):
135200
2. 若k <= |A|,则第k小的元素必然在A中,我们可以丢弃子序列B,然后在A中进一步查找;
136201
3. 若|A| < k,则第k小的元素必然在B中,我们可以丢弃子序列A,然后在B中进一步查找第(k − |A|)小的元素。
137202

138-
注意下划线部分强调了递归的特性。理想情况下,我们总是将序列划分为相 等长度的两个子序列A和B,这样每次都将问题的规模减半,因此性能为线性时 间O(n)。
203+
注意下划线部分强调了递归的特性。理想情况下,我们总是将序列划分为相 等长度的两个子序列A和B,这样每次都将问题的规模减半,因此性能为线性时间O(n)。
139204

140205

141206
关键问题是如何实现划分,将前m小的元素放入一个子序列中,将剩余元素放入另一个中。
@@ -150,4 +215,11 @@ class Solution(object):
150215

151216
4. 若|A| > k − 1,递归在A中寻找第k小的元素;
152217

153-
5. 否则,递归在B中寻找第(k − 1 − |A|)小的元素;
218+
5. 否则,递归在B中寻找第(k − 1 − |A|)小的元素;
219+
220+
221+
222+
223+
224+
225+

0 commit comments

Comments
 (0)