算法分析与设计第二周习题:分治算法之P215,P169,P53

题目链接
题目名称:215. Kth Largest Element in an Array
题目描述:
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.

For example,
Given [3,2,1,5,6,4] and k = 2, return 5.

Note:
You may assume k is always valid, 1 ≤ k ≤ array’s length.


python代码:

class Solution(object):
    def findKthLargest(self, nums, k):
        return recFind(nums, k)

#选取数组中位于中间位置的值作为分水岭分界值
#以分界值将数组分为小于,等于和大于该值的三部分,并统计三部分数组的长度
#根据长度和k值来进行下一步的判定
def recFind(nums, k):
    length = len(nums)
    target = nums[int(length / 2)]
    if length == 1:
        return nums[0]
    smallerCount, biggerCount, equalCount = 0, 0, 0
    smallerList, biggerList = [], []
    for i in range(length):
        if nums[i] < target:
            smallerList.append(nums[i])
            smallerCount += 1
        elif nums[i] > target:
            biggerList.append(nums[i])
            biggerCount += 1
        else:
            equalCount += 1
    #若大值数组长度大于等于k,则在大值数组中寻找kth最大值
    if biggerCount >= k:
        return recFind(biggerList, k)
    #若kth最大值在等值数组中,则可直接返回分界值
    elif biggerCount + equalCount >= k:
        return target
    #若Kth最大值在小值数组中,则减少k的值,并在小值数组中寻找
    else:
        return recFind(smallerList, k - biggerCount - equalCount)

代码效率:
这里写图片描述

总结:
代码使用了老师课上所说的分治算法,并实现了较高的算法效率。
下面贴出了169题和53题的代码,这两道题难度为easy,就不再做详细分析。

169题

int recMaj(vector<int>& nums, int left, int right) {
    if (left == right)
        return nums[left];
    int mid = (left + right) / 2;
    int maj1 = recMaj(nums, left, mid);
    int maj2 = recMaj(nums, mid + 1, right);
    if (maj1 == maj2)
        return maj1;
    else {
        int count1 = 0, count2 = 0;
        for (int i = left; i <= right; i++) {
            if (nums[i] == maj1)
                count1++;
            else if (nums[i] == maj2)
                count2++;
        }
        return count1 < count2 ? maj2 : maj1;
    }
}


class Solution {
public:
    int majorityElement(vector<int>& nums) {
        return recMaj(nums, 0, nums.size() - 1);
    }
};

53题

class Solution(object):
    def maxSubArray(self, nums):
        return divide(nums)

def divide(nums):
    if len(nums) == 1:
        return nums[0]
    length = len(nums)
    mid = int(length / 2)
    #将数组划分为两半
    #并得到两半分别的最大值
    max1 = divide(nums[0:mid])
    max2 = divide(nums[mid:length])
    #计算含边界时的最大值
    maxLBorder,sumLBorder, maxRBorder, sumRBorder = 0, 0, 0, 0
    for i in range(mid, -1, -1):
        sumLBorder += nums[i]
        if sumLBorder > maxLBorder:
            maxLBorder = sumLBorder
    for i in range(mid + 1, length):
        sumRBorder += nums[i]
        if sumRBorder > maxRBorder:
            maxRBorder = sumRBorder
    #若数组全为负数,则直接返回两半中的最大值
    #不考虑边界,是因为把边界最小值设置为0,
    #当数组全为负数时,若考虑边界则程序会返回0,这是错误的
    if (max1 < 0 and max2 < 0):
        return max(max1, max2)
    return max(max1, max2, maxLBorder + maxRBorder)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值