[LeetCode]2020/11/05

[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)

执行结果展示:

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值