给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
进阶:
如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。
class Solution {//滑动窗口
public:
int minSubArrayLen(int s, vector& nums) {
if(nums.size()==0)return 0;
int le=0,ri=0,sum=0,res=INT_MAX;
while(ri=s){
res=min(res,ri-le);
sum-=nums[le++];
}
}
return res==INT_MAX?0:res;
}
};
int minSubArrayLen(int s, vector& nums){
if(nums.size()==0)return 0;
vectorsum(nums.size()+1,0);//s<=sumij=sum[j+1]-sum[i];
int res=INT_MAX;
for(int i=1;i&nums,int low,int high,int target){
if(low>high)return -1;
int le=low,ri=high,pos=-1;
while(le<=ri){
int mid=le+((ri-le)>>1);
if(nums[mid]>=target){
pos=mid;
ri=mid-1;
}
else le=mid+1;
}
return pos;
}
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入:(7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 8 -> 0 -> 7
class Solution {
//如果输入链表不能修改该如何处理?用vector存储起来,从后遍历相加
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
l1=reverse(l1);
l2=reverse(l2);
ListNode *LN=new ListNode(0),*cur=LN;
int carry=0;
while(l1&&l2){
int sum=l1->val+l2->val+carry;
carry=sum/10;
auto tmp=new ListNode(sum%=10);
cur->next=tmp;
cur=tmp;
l1=l1->next;
l2=l2->next;
}
while(l1){
int sum=l1->val+carry;
carry=sum/10;
auto tmp=new ListNode(sum%=10);
cur->next=tmp;
cur=tmp;
l1=l1->next;
}
while(l2){
int sum=l2->val+carry;
carry=sum/10;
auto tmp=new ListNode(sum%=10);
cur->next=tmp;
cur=tmp;
l2=l2->next;
}
if(carry){
auto tmp=new ListNode(1);
cur->next=tmp;
}
cur=LN->next;
delete LN;
return reverse(cur);
}
ListNode* reverse(ListNode* head){
ListNode *pre=nullptr,*cur=head,*next=nullptr;
while(cur){
next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
};
矩形以列表 [x1, y1, x2, y2] 的形式表示,其中 (x1, y1) 为左下角的坐标,(x2, y2) 是右上角的坐标。
如果相交的面积为正,则称两矩形重叠。需要明确的是,只在角或边接触的两个矩形不构成重叠。
给出两个矩形,判断它们是否重叠并返回结果。
示例 1:
输入:rec1 = [0,0,2,2], rec2 = [1,1,3,3]
输出:true
示例 2:
输入:rec1 = [0,0,1,1], rec2 = [1,0,2,1]
输出:false
提示:
两个矩形 rec1 和 rec2 都以含有四个整数的列表的形式给出。
矩形中的所有坐标都处于 -10^9 和 10^9 之间。
x 轴默认指向右,y 轴默认指向上。
你可以仅考虑矩形是正放的情况。
class Solution {
public:
//横坐标+纵坐标重叠的情况
bool isRectangleOverlap(vector& rec1, vector& rec2) {
int lx1=rec1[0],ly1=rec1[1],lx2=rec1[2],ly2=rec1[3];
int rx1=rec2[0],ry1=rec2[1],rx2=rec2[2],ry2=rec2[3];
return max(lx1,rx1)& rec1, vector& rec2) {
int lx1=rec1[0],ly1=rec1[1],lx2=rec1[2],ly2=rec1[3];
int rx1=rec2[0],ry1=rec2[1],rx2=rec2[2],ry2=rec2[3];
return !(lx2<=rx1||lx1>=rx2||ly1>=ry2||ly2<=ry1);
}
*/
};
在 N * N 的网格上,我们放置一些 1 * 1 * 1 的立方体。
每个值 v = grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。
请你返回最终形体的表面积。
示例 1:
输入:[[2]]
输出:10
示例 2:
输入:[[1,2],[3,4]]
输出:34
示例 3:
输入:[[1,0],[0,2]]
输出:16
示例 4:
输入:[[1,1,1],[1,0,1],[1,1,1]]
输出:32
示例 5:
输入:[[2,2,2],[2,1,2],[2,2,2]]
输出:46
提示:
1 <= N <= 50
0 <= grid[i][j] <= 50
class Solution {
vectordx={1,0,-1,0},dy={0,1,0,-1};
public:
int surfaceArea(vector>& grid){
int n=grid.size();
int cnt=0;
for(int i=0;i>& grid) {
int n=grid.size();
int cnt=0;
for(auto &i:grid)
for(auto &j:i)
cnt+=j==0?0:6*j-2*(j-1);//6*j:总 2*(j-1):自身重叠
for(int i=0;i
根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
class Solution {
public:
void gameOfLife(vector>& board){
/*更新后状态<-当前状态:二进制第1位为更新后的状态,第0位为当前状态
0<-0:00 0//
1<-0:10 2
0<-1:01 1//
1<-1:11 3
*/
int n,m;
if((m=board.size())==0||(n=board[0].size())==0)return;
vectordx={1,0,-1,0,1,1,-1,-1};
vectordy={0,1,0,-1,1,-1,1,-1};
for(int i=0;i>=1;//因为二进制第1位为更新后的状态,第0位为当前状态
}
/*
void gameOfLife(vector>& board) {
int n,m;
if((m=board.size())==0||(n=board[0].size())==0)return;
vectordx={1,0,-1,0,1,1,-1,-1};//2
vectordy={0,1,0,-1,1,-1,1,-1};
vector>res(m,vector(n,0));
for(int i=0;i
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
你可以认为 s 和 t 中仅包含英文小写字母。字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 <=100)。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
示例 1:
s = "abc", t = "ahbgdc"
返回 true.
示例 2:
s = "axc", t = "ahbgdc"
返回 false.
后续挑战 :
如果有大量输入的 S,称作S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
方法一:双指针
思路及算法
本题询问的是,sss 是否是 ttt 的子序列,因此只要能找到任意一种 sss 在 ttt 中出现的方式,即可认为 sss 是 ttt 的子序列。
而当我们从前往后匹配,可以发现每次贪心地匹配靠前的字符是最优决策。
假定当前需要匹配字符 ccc,而字符 ccc 在 ttt 中的位置 x1x_1x1 和 x2x_2x2 出现(x1 这样,我们初始化两个指针 iii 和 jjj,分别指向 sss 和 ttt 的初始位置。每次贪心地匹配,匹配成功则 iii 和 jjj 同时右移,匹配 sss 的下一个位置,匹配失败则 jjj 右移,iii 不变,尝试用 ttt 的下一个字符匹配 sss。
最终如果 iii 移动到 sss 的末尾,就说明 sss 是 ttt 的子序列。class Solution {
public:
bool isSubsequence(string s, string t) {
int n = s.length(), m = t.length();
int i = 0, j = 0;
while (i < n && j < m) {
if (s[i] == t[j]) {
i++;
}
j++;
}
return i == n;
}
};
class Solution {
public:
bool isSubsequence(string s, string t) {
int sl=s.size(),tl=t.size();
vector