Quick Sort O(nlogn)
选最后一个num为pivot,从left遍历到right, 比它小的元素全部放到前面去。然后再把自己也放到前面去,它后面的都比它大,
它前面的都比它小。返回它的索引。然后重复 它的左边,和右边按照之前的步骤。
def quickSort(arr, l, r):
if l < r:
idx = partition(arr, l, r)
quickSort(arr, l, idx-1)
quickSort(arr, idx+1, r)
return arr
def partition(arr, l, r):
pivot = arr[r] # pick the rightmost value as pivot
i = l - 1
for j in xrange(l, r):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[r] = arr[r], arr[i+1]
return i+1
Quick Select
# find the kth smallest element in an unsorted array
def quickSelect(arr, l, r, k):
if l == r:
return arr[l]
idx = partition(arr, l, r)
if idx == k:
return arr[k]
elif idx > k:
return quickSelect(arr, l, idx-1, k)
else:
return quickSelect(arr, idx+1, r, k)
# same as quick sort
def partition(arr, l, r):
pivot = arr[r] # pick the rightmost value as pivot
i = l - 1
for j in xrange(l, r):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i+1], arr[r] = arr[r], arr[i+1]
return i+1
Bubble Sort O(n^2)
def bubbleSort(nums):
for i in xrange(len(nums)-1):
for j in xrange(len(nums)-i-1):
if nums[j] > nums[j+1]:
nums[j], nums[j+1] = nums[j+1], nums[j]
return nums
Merge Sort
def mergeSort(nums):
if len(nums) <= 1: return nums
mid = len(nums) / 2
left = mergeSort(nums[:mid])
right = mergeSort(nums[mid:])
return merge(left, right)
def merge(left, right):
res = []
while left and right:
if left[0] < right[0]:
res.append(left.pop(0))
else:
res.append(right.pop(0))
return res + left + right
Bucket Sort
O(n) O(n)
经典排序算法 - 桶排序Bucket sort - kkun - 博客园
1433. Check If a String Can Break Another String
class Solution:
def checkIfCanBreak(self, s1: str, s2: str) -> bool:
'''
sort solution:
s1 = sorted(s1)
s2 = sorted(s2)
a1 = a2 = True
for i in range(len(s1)):
if(s1[i] < s2[i]):
a1 = False
elif(s1[i] > s2[i]):
a2 = False
return a1 or a2
'''
count1 = collections.Counter(s1)
count2 = collections.Counter(s2)
def check(count1, count2):
s = 0
for c in 'abcdefghijklmnopqrstuvwxyz':
s += count1[c] - count2[c]
if s < 0:
return False
return True
return check(count1, count2) or check(count2, count1)
280. Wiggle Sort
class Solution(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
for i in xrange(len(nums)):
if i % 2 == 1:
if nums[i] < nums[i-1]:
nums[i], nums[i-1] = nums[i-1], nums[i]
else:
if i != 0 and nums[i] > nums[i-1]:
nums[i], nums[i-1] = nums[i-1], nums[i]
1996. The Number of Weak Characters in the Game
class Solution:
def numberOfWeakCharacters(self, properties: List[List[int]]) -> int:
properties.sort(key=lambda x: (x[0], -x[1])) # 第二个元素 递减
re, stack = 0, []
# [1,7] [2,5] [3, 9]
for a, b in properties:
while stack and b > stack[-1]:
re += 1
stack.pop()
stack.append(b)
return re
'''
properties.sort(key = lambda x : (-x[0], x[1])) # 第一个元素descending
cur_max = re = 0
for a, b in properties:
if b < cur_max:
re += 1
else:
cur_max = b
return re
'''
179. Largest Number
class Solution(object):
def largestNumber(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
nums = [str(x) for x in nums]
nums = sorted(nums, cmp=lambda a, b: cmp(a+b, b+a), reverse=True)
return "".join(nums).lstrip('0') or '0'
324. Wiggle Sort II
nlogn:
class Solution(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
nums.sort()
half = len(nums[::2])
nums[::2], nums[1::2] = nums[:half][::-1], nums[half:][::-1]
O(n)的很难理解,先复制下别人的答案,回头再来研究:
思路:Loading...
参考:3-partition
class Solution(object):
def wiggleSort(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
if len(nums) == 1:
return
n = len(nums)
# Index-rewiring.
f = lambda i:(1+2*(i)) % (n|1)
mid = self.quickselect(0, len(nums) - 1, nums, len(nums) / 2)
# 3 way partition
i, j, k = 0, 0, n-1
while j <= k:
if (nums[f(j)] > mid):
nums[f(i)], nums[f(j)] = nums[f(j)], nums[f(i)]
i += 1
j += 1
elif nums[f(j)] < mid:
nums[f(j)], nums[f(k)] = nums[f(k)], nums[f(j)]
k -= 1
else:
j += 1
print nums
def quickselect(self, start, end, A, k):
if start == end:
return A[start]
mid = self.partition(start, end, A)
if mid == k:
return A[k]
elif mid > k:
return self.quickselect(start, mid - 1, A, k)
else:
return self.quickselect(mid + 1, end, A, k)
def partition(self, start, end, A):
pivotIndex = random.randrange(start, end + 1)
pivot = A[pivotIndex]
A[end], A[pivotIndex] = A[pivotIndex], A[end]
mid = start
for i in xrange(start, end):
if A[i] >= pivot:
A[mid], A[i] = A[i], A[mid]
mid += 1
A[mid], A[end] = A[end], A[mid]
return mid
253. Meeting Rooms II
Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...]
(si < ei), find the minimum number of conference rooms required.
# Definition for an interval.
# class Interval(object):
# def __init__(self, s=0, e=0):
# self.start = s
# self.end = e
# Very similar with what we do in real life. Whenever you want to start a meeting,
# you go and check if any empty room available (available > 0) and
# if so take one of them ( available -=1 ). Otherwise,
# you need to find a new room someplace else ( numRooms += 1 ).
# After you finish the meeting, the room becomes available again ( available += 1 ).
class Solution(object):
def minMeetingRooms(self, intervals):
"""
:type intervals: List[Interval]
:rtype: int
"""
start, end = [], []
for inter in intervals:
start.append(inter.start)
end.append(inter.end)
start.sort()
end.sort()
index_s = index_e = 0
available = num_rom = 0
while index_s < len(start):
if start[index_s] < end[index_e]:
if available > 0:
available -= 1
else:
num_rom += 1
index_s += 1
else:
available += 1
index_e += 1
return num_rom
937. Reorder Log Files
class Solution(object):
def reorderLogFiles(self, logs):
digits = []
letters = []
# divide logs into two parts, one is digit logs, the other is letter logs
for log in logs:
if log.split()[1].isdigit():
digits.append(log)
else:
letters.append(log)
letters.sort(key = lambda x: (x.split()[1:], x.split()[0]))
result = letters + digits #put digit logs after letter logs
return result
853. Car Fleet
class Solution:
def carFleet(self, target: int, pos: List[int], speed: List[int]) -> int:
'''
Explanation
Sort cars by the start positions pos
Loop on each car from the end to the beginning
Calculate its time needed to arrive the target
cur records the current biggest time (the slowest)
If another car needs less or equal time than cur,
it can catch up this car fleet.
If another car needs more time,
it will be the new slowest car,
and becomes the new lead of a car fleet.
Complexity:
O(NlogN) Quick sort the cars by position. (Other sort can be applied)
O(N) One pass for all cars from the end to start (another direction also works).
O(N) Space for sorted cars.
O(1) space is possible if we sort pos inplace.
'''
time = [float(target - p) / s for p, s in sorted(zip(pos, speed))]
res = cur = 0
for t in time[::-1]:
if t > cur:
res += 1
cur = t
return res