每日编程题 12

所有题目均采用python进行完成

快速指数

求解 a n a^n an
程序采用递归的思路,考虑了部分边界问题

def fast_power(a, n):
    if n == 0:
        return 1
    elif n < 0:
        return 1 / fast_power(a, -n)
    elif n % 2:
        return fast_power(a*a, n//2) * a
    else:
        return fast_power(a*a, n//2)

搜索峰值

峰值:不是最大值,比前一个和后一个大都叫峰值,我们随意返回一个即可
第一个和最后一个可以认为是负无穷大
也采用二分搜索的方法,时间复杂度为O(lgn)
注意 数组是没有排好序 也没有重复值

def search_peak(num):
    return peak(num, 0, len(num)-1)
def peak(num, start, end):
    if start == end:
        return start
    if start+1 == end:
        if num[start] > num[end]:
            return start
        else:
            return end
    mid = (start + end) // 2
    if num[mid] > num[mid - 1] and num[mid] > num[mid + 1]:
        return mid
    elif num[mid] > num[mid-1] and num[mid] < num[mid + 1]:
        return peak(num, mid+1, end)
    else:
        return peak(num, start, mid-1)

查找第k大的值

设置一个pivot,左边的都比该数小,右边的都比该数大,我们不需要完全排序,只需要找到第k大的位置
参考:

https://blog.csdn.net/q1242027878/article/details/54925340

def find_k(num,k):
    if num:
        pos = partition(num, 0, len(num)-1)
        if k > pos+1:
            return find_k(num[pos+1:], k-pos-1)
        elif k < pos+1:
            return find_k(num[:pos], k)
        else:
            return num[pos]
def partition(nums, l, r):
    low = l
    while l < r:
        if nums[l] > nums[r]:
            nums[l], nums[low] = nums[low], nums[l]
            low += 1
        l += 1
    nums[low], nums[r] = nums[r], nums[low]
    return low

计算逆序对

输入[2,4,1,3,5]
输出 3 分别是[2,1],[4,1],[4,3]
当我们没有想法的时候,可以考虑暴力方法,找出所有对,判断是否为逆序对,时间复杂度为O(n^2),程序为:

def count_inv(num):
    count = 0
    for i in range(len(num)):
        for j in range(i+1,len(num)):
            if num[i] > num[j]:
                count += 1
    return count

第二种想法 采用归并排序的思路,
多了一步 判断左右两边大小的代码
代码如下

def merge(left,right):
    result = []
    i,j = 0,0
    inv_count = 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        elif right[j] < left[i]:
            result.append(right[j])
            j += 1
            inv_count += (len(left)-i)
    result += left[i:]
    result += right[j:]
    return result,inv_count

    
def count_inv(num):
    if len(num) < 2:
        return num, 0
    mid = len(num) // 2
    left, inv_left = count_inv(num[:mid])
    right, inv_right = count_inv(num[mid:])
    merged, count = merge(left, right)
    count += (inv_left + inv_right)
    return merged, count
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值