LeetCode第11天 huawei 测试题 滑动窗口

Posted 又南又难

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode第11天 huawei 测试题 滑动窗口相关的知识,希望对你有一定的参考价值。

以下题目来源力扣

209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

class Solution:
    def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        start=0
        end=0
        min_=100001
        sum_=0
        while end<len(nums):
            
            sum_=sum_+nums[end]
            while sum_>=target:
                min_=min(min_,end-start+1)
                sum_=sum_-nums[start]
                start=start+1
            end=end+1
                
        if min_==100001:
            return 0
        return min_

时间复杂度:O(n),其中 n 是数组的长度。指针 start 和 end 最多各移动 n 次。
空间复杂度:O(1)。

3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        start=0
        end=0
        max_=0
        n=len(s)
        temp=[]
        while end<n:
            while s[end] in temp:
                max_=max(max_,end-start) 
                temp.pop(0)
                start=start+1
            temp.append(s[end])
            end=end+1
        return max(max_,end-start)

1004. 最大连续1的个数 III
给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        start=0
        end=0
        max_=0
        n=len(nums)
        count=0
        while end<n:
            if nums[end]==0:
                count=count+1
            while count>k:
                max_=max(max_,end-start)
                # print(max_)
                if nums[start]==0:
                    count=count-1
                start=start+1

            end=end+1
        return max(max_,end-start)

1208. 尽可能使字符串相等
给你两个长度相同的字符串,s 和 t。

将 s 中的第 i 个字符变到 t 中的第 i 个字符需要 |s[i] - t[i]| 的开销(开销可能为 0),也就是两个字符的 ASCII 码值的差的绝对值。

用于变更字符串的最大预算是 maxCost。在转化字符串时,总开销应当小于等于该预算,这也意味着字符串的转化可能是不完全的。

如果你可以将 s 的子字符串转化为它在 t 中对应的子字符串,则返回可以转化的最大长度。

如果 s 中没有子字符串可以转化成 t 中对应的子字符串,则返回 0。

class Solution:
    def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
        start=0
        end=0
        n=len(s)
        max_=0
        cost=0
        while end<n:
            cost=cost+abs(ord(t[end])-ord(s[end]))
            while cost>maxCost:
                max_=max(max_,end-start)
                cost=cost-abs(ord(t[start])-ord(s[start]))
                start=start+1
            end=end+1
        return max(max_,end-start)

LeetCode动态规划训练营(1~5天)

目录

第一天

LeetCode509.斐波拉契数

 LeetCode1137.第N个泰波那契数

第二天

LeetCode.70爬楼梯

LeetCode746.使用最小花费爬楼梯

第三天

经典入门级DP:LeetCode198.打家劫舍

打家劫舍升级:LeetCode213.打家劫舍II

继续打家劫舍:LeetCode740.删除比获得点数

第四天

LeetCode.55跳跃游戏

LeetCode45.跳跃游戏II


第一天

LeetCode509.斐波拉契数

不说了,大一刚开学学会的第一个算法。这波直接回忆童年。

class Solution 
public:
    int fib(int N) 
        if(N<=1)
            return N;
        vector<int> dp(N+1,0);
        dp[0] = 0;
        dp[1] = 1;
        for(int i=2;i<=N;i++)
            dp[i] = dp[i-1]+dp[i-2];
        
        return dp[N];
    
;

 LeetCode1137.第N个泰波那契数

class Solution 
public:
    int tribonacci(int n) 
        int dp[38]=0;
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 1;
        if (n <= 2) 
            return dp[n];
        
        for (int i = 3; i <= n; i++) 
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        
        return dp[n];
    
;

第二天

LeetCode.70爬楼梯

超经典,好像也是剑指offer里面的经典

class Solution 
public:
    int climbStairs(int n) 
        if(n<=2)
            return n;
        vector<int> dp(n+1,0);
        dp[1] = 1;
        dp[2] = 2;
        for(int i=3;i<=n;i++)
            dp[i] = dp[i-1]+dp[i-2];
        
        return dp[n];
    
;

LeetCode746.使用最小花费爬楼梯

思路是每次从上一个或者上上一个最小的体力值的楼梯上爬上来。dp[i] = (cost[i] + min(dp[i-1], dp[i - 2]))

class Solution 
public:
    int minCostClimbingStairs(vector<int>& cost) 
        int N = cost.size();
        vector<int> dp(N, 0);
        dp[0] = cost[0];
        dp[1] = cost[1];
        if (cost.size() == 2) 
            return min(dp[1], dp[0]);
        
        for (int i = 2; i < N; i++) 
            dp[i] = (cost[i] + min(dp[i-1], dp[i - 2]));
        
        return min(dp[N-1], dp[N-2]);
    
;

第三天

经典入门级DP:LeetCode198.打家劫舍

这道题可以说是LeetCode上最经典,出镜率最高的问题之一,据说字节还叫头条的时候,动不动就出这道题来玩……

一开始完全没思路,尿了

看热评第一的大佬:

我只能说,大佬牛逼!!!

解释:

假设偷盗经过了第i个房间时,那么有两种可能,偷第i个房间,或不偷第i个房间。如果偷得话,那么第i-1的房间一定是不偷的,所以经过第I个房间的最大值DP(i)=DP(I-2) +nums[i];如果经过第i房间不偷的话,那么经过第i房间时,偷取的最大值就是偷取前i-1房价的最大值。
这两种方案分别是dp[i-2]+nums[i]和 dp[i-1],取最大值就是经过第i房间的最大值。

class Solution 
public:
    int rob(vector<int>& nums) 
        if (nums.empty())
            return 0;
        else if (nums.size() == 1)
            return nums[0];
        int dp[nums.size()];
        dp[0] = nums[0];
        dp[1] = max(nums[0], nums[1]);
        for (int i = 2; i<nums.size(); i++) 
            // 要么是上一次打劫(上上一家)得到的综合加上这这家打劫的金额
            // 要么是从上面一家开始打劫,之前打劫的不算
            dp[i] = max(dp[i-2] + nums[i], dp[i-1]);
        
        return dp[nums.size()-1];
    
;

打家劫舍升级:LeetCode213.打家劫舍II

 看似是一个有环问题,但是和链表有环那一类有环问题是完全不一样的。

此处的有环问题可以归类为打劫了第一个就不能打劫最后一个,不打劫第一个就能打劫最后一个。

所以此处的有环问题只用这样化解一个就可以了。

class Solution 
public:
    int rob(vector<int>& nums) 
        int N = nums.size();
        vector<int> dp1(N, 0);  // 打劫第一个
        vector<int> dp2(N, 0);  // 不打劫第一个
        if (nums.empty()) 
            return 0;
        
        if (nums.size() == 1) 
            return nums[0];
        
        if (nums.size() == 2) 
            return max(nums[0], nums[1]);
        
        // 分成两段打家劫舍来考虑
        // 打劫了第一个就不能打劫倒数第一个
        dp1[0] = nums[0];
        dp1[1] = max(nums[0], nums[1]);
        for (int i = 2; i < N - 1; i++) 
            dp1[i] = max(dp1[i - 2] + nums[i], dp1[i - 1]);
        
        // 不打劫第一个就能打劫倒数第一个
        dp2[0] = 0;
        dp2[1] = nums[1];
        for (int i = 2; i < N; i++) 
            dp2[i] = max(dp2[i - 2] + nums[i], dp2[i - 1]);
        
        return max(dp1[N - 2], dp2[N - 1]);
    
;

继续打家劫舍:LeetCode740.删除比获得点数

这道题很牛逼,非常牛逼。

我们要删除的点,就是不能挨在一起删除的问题。这和打家劫舍一模一样:不能打劫相同挨在一起的。

所以我们重新构造一个数组,这个数组存储了每中数字之和。

然后用打家劫舍的思维遍历一遍这个数组就OK,非常牛逼啊这个思路!

class Solution 
public:
    int deleteAndEarn(vector<int>& nums) 
        int temp[10001] = 0;
        int dp[10001] = 0;
        for (auto num : nums) 
            temp[num] += num;
           
        dp[0] = 0;
        dp[1] = temp[1];
        for (int i = 2; i < 10001; i++) 
            dp[i] = max(dp[i - 2] + temp[i], dp[i - 1] );
        
        return dp[10000];
    
;

第四天

LeetCode.55跳跃游戏

 用dp维护一个能跳跃到的最大点的位置坐标即可。

class Solution 
public:
    bool canJump(vector<int>& nums) 
        int maxDis = nums[0];
        for (int i = 1; i < nums.size(); i++) 
            if (i <= maxDis)
                maxDis = max(maxDis, nums[i] + i);
        
        return maxDis >= nums.size() - 1;
    
;

LeetCode45.跳跃游戏II

以上是关于LeetCode第11天 huawei 测试题 滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章

20.11.8 leetcode 1,122

LeetCode动态规划训练营(1~5天)

LeetCode动态规划训练营(1~5天)

Alpha冲刺第8天

Alpha冲刺第9天

滑动轮播图实现最后一张图片无缝衔接第一张图片