要求
- 时间限制:1秒
- 空间限制:32768K
- 热度指数:357881
- 本题知识点: 数组
题目描述
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
思路
几种排序算法被写在了一起。
思路一:快排
如果不要求前k个数是有序的也可以用快排来完成,但是这个题目要求了前k个数有序。
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if k <= 0 or k > len(tinput):
return []
self.quickSort(tinput, 0, len(tinput)-1, k)
return tinput[:k]
def quickSort(self, tinput, left, right, k):
if left >= right:
return
index = self.partition(tinput, left, right)
len_left = index - left + 1
# 说明左边已经有多于k个最小数了
if len_left >= k:
self.quickSort(tinput, left, index-1, k)
else:
self.quickSort(tinput, index+1, right, k-len_left)
def partition(self, tinput, left, right):
mid = (right - left) // 2 + left
tinput[left], tinput[mid] = tinput[mid], tinput[left]
tmp = tinput[left]
while left < right:
while left < right and tinput[right] > tmp:
right -= 1
tinput[left] = tinput[right]
while left < right and tinput[left] < tmp:
left += 1
tinput[right] = tinput[left]
tinput[left] = tmp
return left
C++实现
- 运行时间:3ms
- 占用内存:504k
思路二:堆排序
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if k <= 0 or k > len(tinput):
return []
self.res = []
self.heap_sort(tinput, k)
return self.res
def minHeapify(self, tinput, i, heap_size):
left = 2 * i + 1
right = 2 * i + 2
min_index = i
if left < heap_size and tinput[left] < tinput[min_index]:
min_index = left
if right < heap_size and tinput[right] < tinput[min_index]:
min_index = right
if min_index != i:
tinput[i], tinput[min_index] = tinput[min_index], tinput[i]
self.minHeapify(tinput, min_index, heap_size)
def build_min_heap(self, tinput):
start_idx = (len(tinput)-1) // 2
for i in range(start_idx, -1, -1):
self.minHeapify(tinput, i, len(tinput))
def heap_sort(self, tinput, k):
self.build_min_heap(tinput)
for i in range(k):
self.res.append(tinput[0])
tinput[0], tinput[-(i+1)] = tinput[-(i+1)], tinput[0]
self.minHeapify(tinput, 0, len(tinput)-i-1)
C++实现
- 运行时间:4ms
- 占用内存:468k
class Solution {
public:
// 快排
void quickSort(vector<int> &input, int left, int right) {
if (left >= right)
return;
int i = left, j = right, tmp = input[left];
while (i < j) {
while (i<j && input[j]>=tmp) j--;
if (i < j) input[i] = input[j];
while (i<j && input[i]<=tmp) i++;
if (i < j) input[j] = input[i];
}
input[i] = tmp;
quickSort(input, left, i-1);
quickSort(input, i+1, right);
}
// 堆排序
void heapSort(vector<int> &input){
int length = input.size();
if (length <= 1) return;
// 构建初始堆:从右向左,从下到上
for (int i=length/2-1; i>=0; i--)
adjustHeap(input, i, length);
// 开始排序:从左到右,从上到下
for (int j=length-1; j>=0; j--){
swap(input[0], input[j]);
adjustHeap(input, 0, j);
}
}
void adjustHeap(vector<int> &input, int i, int length){
int tmp = input[i]; // tmp保存的值为需要调整的节点的值,i为需要调整的节点
// k为需要调整的节点i的左孩子;如果不需要调整,则直接退出循环
// 如果需要调整,则下次循环需要调整的节点i变成k,即和它交换的那个孩子,k变成当前k的左孩子
for (int k=2*i+1; k<length; k=2*k+1){
// 让k指向比较大的那个孩子节点
if (input[k+1]>input[k])
k = k + 1;
// 判断是否需要调整
if (input[k]>tmp){
swap(input[k], input[i]);
i = k; // 需要交换的节点变成了i的较大的子节点,该子节点的值也变成tmp
}
else
break;
}
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int length = input.size();
vector<int> cut_vector;
if (length < k)
return cut_vector;
// 快排
// quickSort(input, 0, length-1);
// 堆排序
heapSort(input);
// vector<int>::iterator iter1 = input.begin();
// vector<int>::iterator iter2 = input.begin() + k;
// vector<int> cut_vector(iter1, iter2);
for (int i=0; i<k; i++)
cut_vector.push_back(input[i]);
return cut_vector;
}
};
归并排序
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if k <= 0 or k > len(tinput):
return []
res = self.mergeSort(tinput, 0, len(tinput)-1)
return res[:k]
def mergeSort(self, tinput, left, right):
if right == left:
return tinput[left: left+1]
mid = (right - left) // 2 + left
left_part = self.mergeSort(tinput, left, mid)
right_part = self.mergeSort(tinput, mid+1, right)
return self.merge(left_part, right_part)
def merge(self, left_part, right_part):
i, j = 0, 0
res = []
while i < len(left_part) and j < len(right_part):
if left_part[i] < right_part[j]:
res.append(left_part[i])
i += 1
else:
res.append(right_part[j])
j += 1
if i < len(left_part):
return res + left_part[i:]
elif j < len(right_part):
return res + right_part[j:]
else:
return res