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.斐波拉契数
不说了,大一刚开学学会的第一个算法。这波直接回忆童年。
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 测试题 滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章