Python leetcode 1011递归代码的时间复杂性问题

Python leetcode 1011递归代码的时间复杂性问题,python,algorithm,recursion,time-complexity,Python,Algorithm,Recursion,Time Complexity,所以我在做以下问题: 我知道有一个更好的二进制搜索解决方案,但起初我想到了一个递归解决方案,我不太确定用什么最简单的方法来解释它的时间复杂性 基本上,我的蛮力方法是遍历数组的所有长度为D的前缀(每个前缀代表我们可以在第1天发送的潜在包),然后对于每个前缀,只在数组的其余部分递归,递减值为D,计算出在D-1天内装运剩余包裹的最小容量。然后,前缀和递归结果之和的最大值给出了对应于该前缀的最小容量 然后,我基本上要对所有前缀执行此操作,并获得所有前缀的最小容量。代码是这样的。。不过,我不确定我们如何

所以我在做以下问题:

我知道有一个更好的二进制搜索解决方案,但起初我想到了一个递归解决方案,我不太确定用什么最简单的方法来解释它的时间复杂性

基本上,我的蛮力方法是遍历数组的所有长度为D的前缀(每个前缀代表我们可以在第1天发送的潜在包),然后对于每个前缀,只在数组的其余部分递归,递减值为D,计算出在D-1天内装运剩余包裹的最小容量。然后,前缀和递归结果之和的最大值给出了对应于该前缀的最小容量

然后,我基本上要对所有前缀执行此操作,并获得所有前缀的最小容量。代码是这样的。。不过,我不确定我们如何在面试中轻松得出时间复杂度?(这里可能有一个bug,我只是快速记下这段代码来说明这个概念)

现在,我知道我们可以用大多数算法课上教的“展开法”来分析这个问题,所以 如果时间复杂度为T(n),在我的例子中,第一次递归调用后的递归将处理长度为n-1、n-2的数组,依此类推到长度为n-D的数组。这将导致如下递归关系:

T(n)=T(n-1)+T(n-2)+T(n-3)+…+T(n-D)

现在,我可以展开T(n-1)项,然后我会得到以下结果 T(n-1)=T(n-2)+T(n-3)+T(n-1-D)

T(n)=2T(n-1)+T(n-1-D) ^我认为上面的应该简化为2^n或者其他什么,对吗?
我觉得这有点太重了,特别是在面试环境中,有没有更直观的方法来解释为什么是2^n?

我想这个问题是典型的二进制搜索。我不认为你的解决方案会通过“在线评判”,因为时间复杂度很高(你的分析可能是正确的)。但是,您可以测试您的解决方案

在面试环境中,他们所寻找的是最有效的算法,你通常可以在讨论小组中找到。他们甚至不想知道任何关于暴力算法的事情,除非这个问题可能太难了

这可能是O(N logn)时间和恒定内存:

python 输入导入列表中的

类解决方案:
def发货日期(自身,重量:列表[int],d:int)->int:
lo,hi=最大(重量),总和(重量)
当lo>1)#或mid=(lo+hi)//2 | | mid=lo+(hi-lo)//2
cur,必需=0,1
对于以重量表示的重量:
如果电流+重量>中间值:
必需+=1
cur=0
cur+=重量
如果需要>d:
lo=-~mid#简单地说就是lo=mid+1
其他:
高=中
返回lo
JAVA
类解决方案{
公共整数装运天数(整数[]重量,整数d){
int-lo=0;
inthi=0;
用于(整数权重:权重){
lo=数学最大值(lo,重量);
hi+=重量;
}
while(lo>1);
int required=1;
int cur=0;
用于(整数权重:权重){
如果(电流+重量>中间){
所需+=1;
cur=0;
}
cur+=重量;
}
如果需要(需要>d)
lo=-~mid;
其他的
高=中;
}
返回lo;
}
}
C++
类解决方案{
公众:
整数装运天数(向量和权重,整数d){
int-lo=0;
int hi=int_MAX;
用于(整数权重:权重)
lo=最大值(lo,重量);
while(lo>1);
int required=1;
int cur=0;
对于(int index=0;indexd)
lo=-~mid;
其他的
高=中;
}
返回lo;
}
};

我建议在面试时把注意力集中在干净的代码上。您很可能不需要编写t(N)。你可以告诉面试官你的时间/空间复杂性是什么。在采访中,强调“大o”通常不是一个好主意,因为他们可能有不同的观点,更不用说他们寻求实际的大o分析

我建议快速通过bio-o部分。如果面试官会有后续问题,你可以进一步展开

如果你的强项是bio-o,也许你可以花点时间在上面。通常最重要的是算法、数据结构和系统设计/架构

参考文献 这些都是LeetCode的解决方案,顺便提一下,他们设计了一些LeetCode的问题,并且通常在LeetCode的讨论面板上发布最有效的解决方案

有没有更直观的方法来解释为什么是2^n

首先,它不是
2^n
。它确实是指数型的,是n次方的,但这个不一定是2

一点数学知识:任何线性递归关系都允许以
T(n)=A**n
的形式求解,在这种情况下,
A
是特征多项式的根

a ** D = a ** {D-1} + a ** {D-2} + ... + 1
现在你需要证明的是有一个大于1的根,这或多或少是微不足道的。实际上,当
a
等于1时,左侧(即1)小于右侧(即
D
)。随着
a
增长到无穷大,LHS的增长速度比RHS快,并最终变得更大。这意味着存在
a>1
,其中
from typing import List

class Solution:
    def shipWithinDays(self, weights: List[int], d: int) -> int:
        lo, hi = max(weights), sum(weights)
        while lo < hi:
            mid = lo + ((hi - lo) >> 1) # or mid = (lo + hi) // 2 || mid = lo + (hi - lo) // 2
            cur, required = 0, 1
            for weight in weights:
                if cur + weight > mid:
                    required += 1
                    cur = 0
                cur += weight
            if required > d:
                lo = -~mid # simply lo = mid + 1
            else:
                hi = mid

        return lo
class Solution {
    public int shipWithinDays(int[] weights, int d) {
        int lo = 0;
        int hi = 0;

        for (int weight : weights) {
            lo = Math.max(lo, weight);
            hi += weight;
        }

        while (lo < hi) {
            int mid = lo + ((hi - lo) >> 1);
            int required = 1;
            int cur = 0;

            for (int weight : weights) {
                if (cur + weight > mid) {
                    required += 1;
                    cur = 0;
                }

                cur += weight;
            }

            if (required > d)
                lo = -~mid;

            else
                hi = mid;
        }

        return lo;
    }
}
class Solution {
public:
    int shipWithinDays(vector<int> &weights, int d) {
        int lo = 0;
        int hi = INT_MAX;

        for (int weight : weights)
            lo = max(lo, weight);

        while (lo < hi) {
            int mid = lo + ((hi - lo) >> 1);
            int required = 1;
            int cur = 0;

            for (int index = 0; index < weights.size() && required <= d; cur += weights[index++])
                if (cur + weights[index] > mid)
                    cur = 0, required++;

            if (required > d)
                lo = -~mid;

            else
                hi = mid;

        }

        return lo;
    }
};
a ** D = a ** {D-1} + a ** {D-2} + ... + 1