实用性算法二则:来自leetcode321

一、

求最大字典序子数组算法:

此算法用来求解最大子数:
一般性问题描述为,有一个数组[a0,a1,a2....an] ,其中ai 是0~9 的整数 。需要我们拿出k个数,按照原数组的顺序来组合成一个数
使得:此数的值或者此数组的字典序最大。

算法基本思路:

利用一个栈,因为尽可能高位要放更大的数,所以应按照递减顺序来存放,也就是递减栈用法
1,如果最终结果得到的栈太小,不能构成k位数组,那么需要一个变量来限制弹出个数
2,如果最终得到的栈过大,我们取前k个数

这个算法可以说是贪心算法+栈实现的

代码:

def get_arr(nums, n):
    stk = []
    poped = len(nums) - n
    if poped == 0:
        return nums[:]
    if n == 0:
        return []
    for i in range(len(nums)):
        while len(stk) > 0 and poped > 0 and stk[-1] < nums[i]:
            stk.pop()
            poped -= 1
        stk.append(nums[i])
    return stk[:n]

二、

多数组合并算法:

这里实际上合并了两个。

顺便说一句,可迭代对象的比较需要O(min(n,m))的时间。

也就是说为了比较出【1,3,5,7,6】>【1,3,5,2】需要4次基本元素比较

要诀在于每次比较后我们将取用比较大的对象的首元素来构造新数组。

举个例子:a1=[3,2,3],a2=[4,2]

按照“高位的元素尽可能的大”,我们知道肯定需要a2的首元素,取出4.

a1=[3,2,3],a2=[2],接下来取a1的3。

a1=[2,3],a2=[2],那么问题来了,合并时取哪个2才会更大呢?

我们可以分别来看,如取第一个,那么会构成【2,3,2】,取第二个,会构成【2,2,3】

显然取第一个会得到更大的合并序列。

那么原理是什么呢?在取2那一步,a1>a2,说明取第一个2会尽量保持整体更大,也就是贪心算法。

所以换个角度:a1=23,a2=2,去掉a1的2相当于a1缩小了20,但是去掉a2的只能让它减小2,因为合并a1(23)与a2(2)后能得到三位数,所以百位一定是2,但是十位就与更大的那个子数有关了。

因此,每一次添加数字就该比较一次。

def merge_arr(arr1,arr2):
            rec=[]
            from collections import deque
            q1,q2=deque(arr1),deque(arr2)
            while len(q1)+len(q2)>0:
                temp=q1 if q1>q2 else q2
                rec.append(temp.popleft())
            return rec

三、leetcode321

依靠这两个算法

分别取(0,k),(1,k-1),(2,k-2)。。。个数

依靠合并算法来取最大值即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值