【LeetCode刷题】53 最大字序和 || 60 第k个排列

53、最大字序和

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和

示例 1:
输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

暴力法

def Maxarray(nums):
    maxnum = max(nums)
    for i in range(len(nums)):
        tmp = 0
        for j in range(i,len(nums)):
            tmp += nums[j]
            if tmp>maxnum:
                maxnum = tmp
    return maxnum

print(Maxarray([-2,1,-3,4,-1,2,1,-5,4]))

动态规划

假如我们现在有一个序列 nums=[-2, 3, -1, 1, -3],要计算这个序列的最大子序列。假设 sum = 0,加上第一个元素后 sum = -2,目前-2是最大的数,接着我们加上第二个元素3,我们会发现加上以后 sum = 1 ,现在的最大数应该是3,所以我们应该舍弃-2,直接令 sum = 3。简单的数就是正数增益,当 sum <= 0的时候,就舍弃前面所有的元素,从当前元素开始相加,并记录相加过程中最大的值。

def maxSubArray(nums):
    sum = 0
    max = nums[0]

    for index in range(len(nums)):
        if sum < 0:
            sum = 0
        sum += nums[index]
        if sum > max:
            max = sum
    return max

print(maxSubArray([-2,-1,-3,-4,-1,-2,-1,-5,-4]))

60、第K个排列

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。

说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。

def getPermutation(n, k):
    l = []
    s = ''
    t = 1
    for i in range(0, n):
        t = t * (i + 1)
        l.append(i + 1)

    for c in range(0, n - 1):
        t = t / (n - c)
        a = (k - 1) // t
        a = int(a)
        s = s + str(l[a])
        l.remove(l[a])
        k = k % t

    s = s + str(l[0])
    return s

方法二:

比如n=4,证明一共有4!种排序,那我们当前的第k个排序是什么呢?我们先确定这个排序的第一个数字。我们知道对于每个数字开头的序列,在它确定的情况下,一共有(n-1)!种情况。比如1开头的n=4的序列,一共有3!种情况。那我们就可以通过k//(n-1)!来确定这是以哪个数字开头的序列,如果等于0,那就是1,如果等于1那就是2,以此类推

class Solution:
    def getPermutation(self, n, k):
        """
        :type n: int
        :type k: int
        :rtype: str
        """
        # 0的阶乘一直到9!
        # 因为题目说了n<=9
        self.fac = [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
        # 找到对应的n应该对应的fac坐标,就是在第一项确定的情况一下,有(n-1)!种组合
        i = n - 1
        # 构建序列,这个num是用来储存我们当前可以添加的数的,也是为避免重复
        num = list(range(1, n + 1))
        ret = ""
        while i >= 0:
            # a用来获得我们要求的那一位在num里的下标
            a, b = k // self.fac[i], k % self.fac[i]
            # 如果刚好整除干净,证明还在上一层
            if b == 0:
                a -= 1

            if a >= 0:
                ret += str(num[a])
                del num[a]
                i -= 1
            k = b
            # 如果刚好整除完,则我们已经可以知道接下来的排序情况了,它一定是最大的
            # 所以把剩下的可选的数字reverse来制造这种效果
            if b == 0:
                for i in reversed(num):
                    ret += str(i)
                break
        return ret
print(Solution().getPermutation(4,9))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值