给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:
s = "barfoothefoobarman",
words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:
s = "wordgoodgoodgoodbestword",
words = ["word","good","best","word"]
输出:[]
class Solution {//滑动窗口:每个words[i]当作一个整体,循环滑动words[0].size()次数
public:
vector<int> findSubstring(string s, vector<string>& words) {
if(s.size()==0||words.size()==0||words[0].size()==0)return {};
vector<int>res;
int w1=words.size(),w2=words[0].size();
int le,ri,valid,len=w1*w2;
unordered_map<string,int>need,windows;
for(auto &i:words)
++need[i];
for(int i=0;i<w2;++i){
le=i,ri=i,valid=0;
while(ri<s.size()){
auto tmp=s.substr(ri,w2);
ri+=w2;
if(need.count(tmp))
if(++windows[tmp]==need[tmp])
++valid;
if(ri-le==len){
if(valid==need.size())//不是valid==w1,因为有重复字符串的可能性
res.push_back(le);
auto tmp=s.substr(le,w2);
le+=w2;
if(need.count(tmp))
if(windows[tmp]--==need[tmp])
--valid;
}
}
windows.clear();//
}
return res;
}
};
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。
空白格用 '.' 表示。
一个数独。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9 和字符 '.' 。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9 形式的。
class Solution {
vector<vector<bool>>rowCol;
vector<vector<bool>>nine;
vector<int>sel;
public:
void solveSudoku(vector<vector<char>>& board) {
rowCol.resize(18,vector<bool>(9,false)); //
nine.resize(9,vector<bool>(9,false));//
for(int i=0;i<9;++i)
for(int j=0;j<9;++j)
if(board[i][j]!='.'){
rowCol[i][board[i][j]-'1']=true;//
rowCol[9+j][board[i][j]-'1']=true; //
nine[i/3*3+j/3][board[i][j]-'1']=true;//
}
else sel.push_back(i*9+j);//待填位置
backTrace(board,sel,0);
}
bool backTrace(vector<vector<char>>& board,vector<int>&sel,int start){
if(start==sel.size())return true;
int i=sel[start]/9,j=sel[start]%9; //
for(int k=0;k<9;++k)
if(!rowCol[i][k]&&!rowCol[9+j][k]&&!nine[i/3*3+j/3][k]){//
rowCol[i][k]=true;
rowCol[9+j][k]=true;
nine[i/3*3+j/3][k]=true;
board[i][j]='1'+k;
if(backTrace(board,sel,start+1))
return true;
board[i][j]='.';
rowCol[i][k]=false;
rowCol[9+j][k]=false;
nine[i/3*3+j/3][k]=false;
}
return false;
}
};
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
class Solution {
//在一个有序数组中找第一个大于等于 target 的下标
public:
int searchInsert(vector<int>& nums, int target) {
int le=0,ri=nums.size()-1;
//if(target>nums[ri])return ri;
int pos=ri+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;
}
/*
int helper(vector<int>& nums, int le,int ri,int target){
if(le>ri)return -1;
if(target<nums[le])return 0;
if(target>nums[ri])return ri+1;
while(le<=ri){
int mid=le+((ri-le)>>1);
if(nums[mid]==target)return mid;
else if(nums[mid]>target)ri=mid-1;
else le=mid+1;
}
return le;
}*/
};
你是产品经理,目前正在带领一个团队开发新的产品。不幸的是,你的产品的最新版本没有通过质量检测。由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。
假设你有 n 个版本 [1, 2, ..., n],你想找出导致之后所有版本出错的第一个错误的版本。
你可以通过调用 bool isBadVersion(version) 接口来判断版本号 version 是否在单元测试中出错。实现一个函数来查找第一个错误的版本。你应该尽量减少对调用 API 的次数。
示例:
给定 n = 5,并且 version = 4 是第一个错误的版本。
调用 isBadVersion(3) -> false
调用 isBadVersion(5) -> true
调用 isBadVersion(4) -> true
所以,4 是第一个错误的版本。
class Solution {
public:
int firstBadVersion(int n) {
int le=0,ri=n;
int pos=-1;
while(le<=ri){
int mid=le+((ri-le)>>1);
if(isBadVersion(mid)){
pos=mid;
ri=mid-1;
}
else le=mid+1;
}
return pos;
}
};