文章目录
[LeetCode]2020/11/05
LeetCode 88
题目描述
这是一道 简单题,核心就是合并两个有序数组
Java的小技巧
在LeetCode的官方解题思路中看到以下写法,在此做个记录
public void merge(int[] nums1, int m, int[] nums2, int n) {
System.arraycopy(nums2, 0, nums1, m, n);
Arrays.sort(nums1);
}
使用java的api,时间复杂度为 O ( m + n ) O(m+n) O(m+n) ,空间复杂度为 O ( 1 ) O(1) O(1)
Python的小技巧
这个也是调用Python的api
nums[:] = sorted(nums1[:m] + nums2)
时间复杂度 O ( ( n + m ) l o g ( n + m ) ) O((n+m)log(n+m)) O((n+m)log(n+m)),空间复杂度 O ( 1 ) O(1) O(1)
有意思的解题思路
采用逆向思维,使用双指针从后往前遍历,既保证了空间复杂度为 O ( 1 ) O(1) O(1),又保证了时间复杂度是 O ( n + m ) O(n+m) O(n+m)
p1, p2 = m-1,n-1
p = m + n-1
while p1 >= 0 and p2 >= 0:
if nums1[p1] < nums2[p2]:
nums1[p] = nums2[p2]
p2 -= 1
else:
nums1[p] = nums1[p1]
p1 -= 1
p -= 1
# 此处是当nums1没有数时,将nums2的全部复制过去
nums1[:p2+1] = nums2[:p2+1]
LeetCode 215
题目描述
这是一道中等题,找出数组中第K大的数字
我自己采用的是选择排序,外循环是k次,找出第k大的。执行结果如下图所示:
其他解题思路—快速排序
// 快速排序算法实现
public void swap(int a, int b, int[] nums){
int tmp = nums[a];
nums[a] = nums[b];
nums[b] = tmp;
}
//根据轴值调整数组,返回轴值最终所在位置
public int partition(int left, int right, int pivot_index, int[] nums){
int pivot = nums[pivot_index];
swap(pivot_index, right, nums);
int store_index = left;
for (int i = left; i <= right; i++){
if(nums[i] < pivot){
swap(store_index, i, nums);
store_index++;
}
}
swap(store_index, right, nums);
return store_index;
}
public int quickselect(int left, int right, int k_smallest, int [] nums) {
if (left == right){
return nums[left];
}
Random random_num = new Random();
int pivot_index = left + random_num.nextInt(right - left);
pivot_index = partition(left, right, pivot_index, nums);
if (k_smallest == pivot_index)
return nums[k_smallest];
else if (k_smallest < pivot_index)
return quickselect(left, pivot_index-1, k_smallest, nums);
return quickselect(pivot_index+1, right, k_smallest, nums);
}
public int findKthLargest_quicksort(int[] nums, int k) {
int size = nums.length;
return quickselect(0, size-1, size-k, nums);
}
执行结果展示:
其他解题思路—堆排序
此处的堆排序采用的是大根堆,重点注意自下而上的大根堆调整方式以及输出的边界条件N-k和配套返回nums[0]
对于为什么是N-k,首先因为采用的是返回固定下标即nums[0]处的数,因为正数第k个 就是倒数第N-k+1个,而在第N-k次的时候nums[0]处就是要取的第k大的数
class Solution:
def PercDown(self, nums:List[int], index: int, N: int)->None:
tmp = nums[index]
while 2*index+1 < N : # 说明还存在孩子,即是非叶子节点
child = 2*index+1
if child != N-1 and nums[child+1] > nums[child]:
child += 1
if nums[index] < nums[child]:
tmp = nums[index]
nums[index] = nums[child]
nums[child] = tmp
else:
break
index = child
def findKthLargest(self, nums: List[int], k: int) -> int:
N = len(nums)
for i in range(N//2, -1, -1):
self.PercDown(nums, i, N)
for i in range(N-1, N-k, -1):
tmp = nums[i]
nums[i] = nums[0]
nums[0] = tmp
self.PercDown(nums, 0, i)
return nums[0]
堆排序的时间复杂度由建堆 O ( n ) O(n) O(n)和调整堆 O ( l o g n ) O(logn) O(logn)两部分组成,一般认为是 O ( n l o g n ) O(nlogn) O(nlogn),空间复杂度因为递归所以是 O ( l o g n ) O(logn) O(logn)
执行结果展示: