1、Wildcard Matching
Implement wildcard pattern matching with support for '?'
and '*'
.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false
感谢水中的鱼,这个题目在现实中也很有用,在正则表达式中。
class Solution {
public:
/*这个题非常好
熟悉通配符,熟悉正则表达式
主要是*的匹配问题。p每遇到一个*,就保留住当前*的坐标和s的坐标,然后s从前往后扫描,如果不成功,则s++,重新扫描。
http://fisherlei.blogspot.sg/2013/01/leetcode-wildcard-matching.html
*/
bool isMatch(const char *s, const char *p) {
bool star = false;
const char * str, *ptr;
for(str = s,ptr = p;*str!='\0';str++,ptr++){
switch(*ptr){
case '?':
break;
case '*':
star = true;
s=str, p = ptr;
while(*p=='*'){
p++;
}
if(*p == '\0'){
return true;
}
str = s-1;
ptr = p-1;
break;
default:
{
if(*ptr != *str){
if(!star){
return false;
}
s++;
str = s-1;
ptr = p-1;
}
}
}
}
while(*ptr == '*'){
ptr++;
}
return (*ptr == '\0');
}
};
2、Combination Sum && Combination Sum II
class Solution {
public:
/*这个题非常好
熟悉通配符,熟悉正则表达式
主要是*的匹配问题。p每遇到一个*,就保留住当前*的坐标和s的坐标,然后s从前往后扫描,如果不成功,则s++,重新扫描。
http://fisherlei.blogspot.sg/2013/01/leetcode-wildcard-matching.html
*/
bool isMatch(const char *s, const char *p) {
bool star = false;
const char * str, *ptr;
for(str = s,ptr = p;*str!='\0';str++,ptr++){
switch(*ptr){
case '?':
break;
case '*':
star = true;
s=str, p = ptr;
while(*p=='*'){
p++;
}
if(*p == '\0'){
return true;
}
str = s-1;
ptr = p-1;
break;
default:
{
if(*ptr != *str){
if(!star){
return false;
}
s++;
str = s-1;
ptr = p-1;
}
}
}
}
while(*ptr == '*'){
ptr++;
}
return (*ptr == '\0');
}
};
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7
and target 7
,
A solution set is:
[7]
[2, 2, 3]
class Solution {
public:
/*这个问题一开始考虑是没有解的,因为是指数类型的嘛,就是背包问题
但是,解法也是指数类型的,
直接每个往里面试就可以了,递归解决。
*/
vector<vector<int>> ret;
vector<int> solution;
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
int sum = 0;
sort(candidates.begin(),candidates.end());
getCombinations(candidates,sum,0,target);
return ret;
}
void getCombinations(vector<int>&candidates,int &sum,int level,int target){
if(sum>target){
return;
}
if(sum == target){
ret.push_back(solution);
return;
}
for(int i = level;i<candidates.size();i++){
sum += candidates[i];
solution.push_back(candidates[i]);
getCombinations(candidates,sum,i,target);
solution.pop_back();
sum -= candidates[i];
}
}
};
class Solution {
public:
/*这个问题一开始考虑是没有解的,因为是指数类型的嘛,就是背包问题
但是,解法也是指数类型的,
直接每个往里面试就可以了,递归解决。
*/
vector<vector<int>> ret;
vector<int> solution;
vector<vector<int> > combinationSum(vector<int> &candidates, int target) {
int sum = 0;
sort(candidates.begin(),candidates.end());
getCombinations(candidates,sum,0,target);
return ret;
}
void getCombinations(vector<int>&candidates,int &sum,int level,int target){
if(sum>target){
return;
}
if(sum == target){
ret.push_back(solution);
return;
}
for(int i = level;i<candidates.size();i++){
sum += candidates[i];
solution.push_back(candidates[i]);
getCombinations(candidates,sum,i,target);
solution.pop_back();
sum -= candidates[i];
}
}
};
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
Note:
- All numbers (including target) will be positive integers.
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
- The solution set must not contain duplicate combinations.
For example, given candidate set 10,1,2,7,6,1,5
and target 8
,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
class Solution {
public:
vector<vector<int>> ret;
vector<int> solution;
vector<vector<int> > combinationSum2(vector<int> &num, int target) {
int sum = 0;
sort(num.begin(),num.end());
getCom(num,sum,0,target);
return ret;
}
void getCom(vector<int>&num,int &sum,int level,int target){
if(sum>target){
return;
}
if(sum==target){
ret.push_back(solution);
return;
}
for(int i=level;i<num.size();i++){
sum+=num[i];
solution.push_back(num[i]);
getCom(num,sum,i+1,target);//可以保证相同的数据每次递归唯一使用
solution.pop_back();
sum-=num[i];
while(i<num.size()-1&&num[i]==num[i+1]){//这里表示在本次递归中用过该数,后面就不能用了。
i++;
}
}
}
};
3、Search for a Range
Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
vector<int> searchRange(int A[], int n, int target) {
vector<int> ret(2,-1);
if(n==0){
return ret;
}
int left = 0,right = n-1;
int mid = 0;
while(left<=right){
mid = (left+right)/2;
if(A[mid]==target){
break;
}
else if(A[mid]>target){
right = mid-1;
}
else{
left = mid+1;
}
}
if(A[mid]!=target){
return ret;
}
left = mid;
while(A[left]==target&&left<n){
left--;
}
right = mid;
while(A[right]==target&&right<n){
right++;
}
ret[0] = left+1;
ret[1] = right-1;
return ret;
}
vector<int> searchRange(int A[], int n, int target) {
vector<int> ret(2,-1);
if(n==0){
return ret;
}
int left = 0,right = n-1;
int mid = 0;
while(left<=right){
mid = (left+right)/2;
if(A[mid]==target){
break;
}
else if(A[mid]>target){
right = mid-1;
}
else{
left = mid+1;
}
}
if(A[mid]!=target){
return ret;
}
left = mid;
while(A[left]==target&&left<n){
left--;
}
right = mid;
while(A[right]==target&&right<n){
right++;
}
ret[0] = left+1;
ret[1] = right-1;
return ret;
}
4、Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6]
, 5 → 2
[1,3,5,6]
, 2 → 1
[1,3,5,6]
, 7 → 4
[1,3,5,6]
, 0 → 0
我用的是从后往前遍历,然后这样的话,复杂度是n,也可以二分,然后查找会更快logn
class Solution {
public:
int searchInsert(int A[], int n, int target) {
if(n == 0){
return 0;
}
int ret = 0;
int i;
for(i = 0;i<n;i++){
if(A[i]==target){
return i;
}
else if(A[i]>target){
return i;
}
}
return i;
}
};
class Solution {
public:
int searchInsert(int A[], int n, int target) {
if(n == 0){
return 0;
}
int ret = 0;
int i;
for(i = 0;i<n;i++){
if(A[i]==target){
return i;
}
else if(A[i]>target){
return i;
}
}
return i;
}
};
5、Valid Sudoku I II
Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
The Sudoku board could be partially filled, where empty cells are filled with the character '.'
.
A partially filled sudoku which is valid.
Note:
A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.
9宫格,行列都必须有9个数字,然后三行三列的小方格也必须有九个数字。题目要求只是填上的数字检测,没有说空格的事情。
class Solution {
public:
/*
先检查,行,列,然后检查9格
*/
bool isValidSudoku(vector<vector<char> > &board) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if(board.size() == 0) return false;
int row[9], col[9];
for(int i =0; i<9; i++)
{
memset(row, 0, 9*sizeof(int));
memset(col, 0, 9*sizeof(int));
for(int j =0; j<9; j++)
{
if(board[i][j] != '.')
{
if(row[board[i][j]-49] ==1)
return false;
row[board[i][j]-49]++;
}
if(board[j][i] != '.')
{
if(col[board[j][i]-49] ==1)
return false;
col[board[j][i]-49]++;
}
}
}
for(int i =0; i< 9; i+=3)
{
for(int j =0; j<9; j+=3)
{
memset(row, 0, 9*sizeof(int));
for(int m=0; m<3; m++)
{
for(int n =0; n<3; n++)
{
if(board[m+i][n+j] == '.')
continue;
if(row[board[m+i][n+j]-49] ==1)
return false;
row[board[m+i][n+j]-49]++;
}
}
}
}
return true;
}
};
Write a program to solve a Sudoku puzzle by filling the empty cells.
Empty cells are indicated by the character '.'
.
You may assume that there will be only one unique solution.
这个就是将九宫格进行添加数字,然后得到正确的结果,而且题目中也明确表示,只有一个答案。现将所有的空格添加入vector,然后挨个的去尝试,先从1开始尝试,然后一直尝试到9,如果不成功,则回溯,并将当前的置空。
struct Position {
int row;
int col;
};
class Solution {
public:
/*
先检查行列,然后检查9格
回溯法
*/
inline bool isValid(vector<vector<char> > &board, Position &p) {
char val = board[p.row][p.col];
if(val < '1' || val > '9') return false;
//cout<<val<<"vT";
//1.check row
vector<char> &brow = board[p.row];
const int width = brow.size();
for(int ic = 0; ic < width; ++ ic) {
if(ic != p.col
&& brow[ic] != '.'
&& brow[ic] == val) {
//cout<<brow[ic]<<"rF";
return false;
}
}
//cout<<"rT";
//2.check column
const int height = board.size();
for(int ir = 0 ; ir < height; ++ir) {
if(ir != p.row
&& board[ir][p.col] != '.'
&& board[ir][p.col] == val)
return false;
}
//3.check 3*3 grid
const int baseri = p.row / 3 * 3;
const int baseci = p.col / 3 * 3;
for(int ir = baseri; ir < baseri + 3; ++ir) {
for(int ic = baseci; ic < baseci + 3; ++ic) {
if(ir != p.row && ic != p.col
&& board[ir][ic] != '.'
&& board[ir][ic] == val)
return false;
}
}
//cout<<"T";
return true;
}
void solveSudoku(vector<vector<char> > &board) {
static int times = 0;
//if(times ++ > 0) return;
vector<Position> pts;//empty positions
int rows = board.size();
if(0 == rows) return;
int cols = board[0].size();
if(0 == cols) return;
//1.found all the empties
for(int ir = 0 ; ir < rows; ++ir) {
for(int ic = 0; ic < cols; ++ ic) {
if(board[ir][ic] == '.') {
Position p;
p.row = ir;
p.col = ic;
pts.push_back(p);
}
}
}
if(pts.size() == 0) return;//no empty cells
//2.back tracing to fill the empties
int curi = 0;
bool forward = true;
board[pts[curi].row][pts[curi].col] = '1';
while(curi >= 0) {
if(curi >= pts.size()) return;
Position &curPt = pts[curi];
if(forward) {
bool valid = isValid(board,curPt);
if(valid) {
++curi;
} else {
forward = false;
}
} else {
char &c = board[curPt.row][curPt.col];
if(c == '9') {
//no siblings
c = '.';
--curi;
} else {
c += 1;
forward = true;
}
}
}
}
};
6、Next Permutation
struct Position {
int row;
int col;
};
class Solution {
public:
/*
先检查行列,然后检查9格
回溯法
*/
inline bool isValid(vector<vector<char> > &board, Position &p) {
char val = board[p.row][p.col];
if(val < '1' || val > '9') return false;
//cout<<val<<"vT";
//1.check row
vector<char> &brow = board[p.row];
const int width = brow.size();
for(int ic = 0; ic < width; ++ ic) {
if(ic != p.col
&& brow[ic] != '.'
&& brow[ic] == val) {
//cout<<brow[ic]<<"rF";
return false;
}
}
//cout<<"rT";
//2.check column
const int height = board.size();
for(int ir = 0 ; ir < height; ++ir) {
if(ir != p.row
&& board[ir][p.col] != '.'
&& board[ir][p.col] == val)
return false;
}
//3.check 3*3 grid
const int baseri = p.row / 3 * 3;
const int baseci = p.col / 3 * 3;
for(int ir = baseri; ir < baseri + 3; ++ir) {
for(int ic = baseci; ic < baseci + 3; ++ic) {
if(ir != p.row && ic != p.col
&& board[ir][ic] != '.'
&& board[ir][ic] == val)
return false;
}
}
//cout<<"T";
return true;
}
void solveSudoku(vector<vector<char> > &board) {
static int times = 0;
//if(times ++ > 0) return;
vector<Position> pts;//empty positions
int rows = board.size();
if(0 == rows) return;
int cols = board[0].size();
if(0 == cols) return;
//1.found all the empties
for(int ir = 0 ; ir < rows; ++ir) {
for(int ic = 0; ic < cols; ++ ic) {
if(board[ir][ic] == '.') {
Position p;
p.row = ir;
p.col = ic;
pts.push_back(p);
}
}
}
if(pts.size() == 0) return;//no empty cells
//2.back tracing to fill the empties
int curi = 0;
bool forward = true;
board[pts[curi].row][pts[curi].col] = '1';
while(curi >= 0) {
if(curi >= pts.size()) return;
Position &curPt = pts[curi];
if(forward) {
bool valid = isValid(board,curPt);
if(valid) {
++curi;
} else {
forward = false;
}
} else {
char &c = board[curPt.row][curPt.col];
if(c == '9') {
//no siblings
c = '.';
--curi;
} else {
c += 1;
forward = true;
}
}
}
}
};
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
![](https://img-blog.csdn.net/20141016125716203?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3FpbmcwMDg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
1、从右到左找到第一个非递增的数,这里6被选中
2、从右到左,找到第一个大于6的数,这里7被选中
3、交换,6,7位置
4、将7右边的所有数据reverse
class Solution {
public:
/*
http://fisherlei.blogspot.sg/2012/12/leetcode-next-permutation.html
*/
void nextPermutation(vector<int> &num) {
int n = num.size();
if(n<=0){
return ;
}
int i = n-1;
int pre = num[n-1];
while(i>=0){
if(num[i] < pre){
break;
}
/*这里粗心拉了一句*/
pre = num[i];
i--;
}
if(i==-1){
reverse(num.begin(),num.end());
return;
}
int firstone = i;
pre = num[i];
i=n-1;
while(i>firstone){
if(num[i]>pre){
break;
}
i--;
}
int lastone = i;
swap(num[firstone],num[lastone]);
firstone++;
lastone = n-1;
while(firstone<lastone){
swap(num[firstone++],num[lastone--]);
}
}
};
class Solution {
public:
/*
http://fisherlei.blogspot.sg/2012/12/leetcode-next-permutation.html
*/
void nextPermutation(vector<int> &num) {
int n = num.size();
if(n<=0){
return ;
}
int i = n-1;
int pre = num[n-1];
while(i>=0){
if(num[i] < pre){
break;
}
/*这里粗心拉了一句*/
pre = num[i];
i--;
}
if(i==-1){
reverse(num.begin(),num.end());
return;
}
int firstone = i;
pre = num[i];
i=n-1;
while(i>firstone){
if(num[i]>pre){
break;
}
i--;
}
int lastone = i;
swap(num[firstone],num[lastone]);
firstone++;
lastone = n-1;
while(firstone<lastone){
swap(num[firstone++],num[lastone--]);
}
}
};
7、Longest Valid Parentheses
Given a string containing just the characters '('
and ')'
, find the length of the longest valid (well-formed) parentheses substring.
For "(()"
, the longest valid parentheses substring is "()"
, which has length = 2.
Another example is ")()())"
, where the longest valid parentheses substring is "()()"
, which has length = 4.
有一些不同,这个是求substring,也就是子串要连续的,所以做的过程中是寻找最长子串的。
int longestValidParentheses(string s) {
const char * str = s.c_str();
int nMax = 0;
const char *p = str;
vector<const char *> sta;
while(*p!='\0'){
if(*p=='('){
sta.push_back(p);
}
else{
if(!sta.empty()&&*sta.back()=='('){
sta.pop_back();
nMax = max(nMax,p-(sta.empty()?str-1:sta.back()));//减地址
}
else{
sta.push_back(p);
}
}
p++;
}
return nMax;
}
8、Count and Say
类似于智力题目,但是只要一直往下写就可以了。一开始没有任何思路,后来想了想,其实堆栈应该也可是可以的。
int longestValidParentheses(string s) {
const char * str = s.c_str();
int nMax = 0;
const char *p = str;
vector<const char *> sta;
while(*p!='\0'){
if(*p=='('){
sta.push_back(p);
}
else{
if(!sta.empty()&&*sta.back()=='('){
sta.pop_back();
nMax = max(nMax,p-(sta.empty()?str-1:sta.back()));//减地址
}
else{
sta.push_back(p);
}
}
p++;
}
return nMax;
}
上一个数用堆栈,下一个数存储在队列里面,然后迭代进行计算。
这里用了string的输入输出流,stringstream
The count-and-say sequence is the sequence of integers beginning as follows:
1, 11, 21, 1211, 111221, ...
1
is read off as "one 1"
or 11
.
11
is read off as "two 1s"
or 21
.
21
is read off as "one 2
, then one 1"
or 1211
.
Given an integer n, generate the nth sequence.
Note: The sequence of integers will be represented as a string.
class Solution {
public:
string countAndSay(int n) {
string seq = "1";
for(int i = 1;i<n;i++){
seq = getnext(seq);
}
return seq;
}
string getnext(string cur){
char last = cur[0];
string ret = "";
int count = 0;
stringstream newSeq;
for(int i = 0;i<=cur.size();i++){
if(cur[i]==last){
count++;
continue;
}
else{
newSeq<<count<<last;
last = cur[i];
count = 1;
}
}
return newSeq.str();
}
};
9、Implement strStr()
曾经的阿里给的一个面试题目。
Implement strStr().
Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
char *strStr(char *haystack, char *needle) {
int len2;
if (!(len2 = strlen(needle)) )
return (char *)haystack;
while(*haystack!='\0'){
if(*haystack == *needle && strncmp(haystack,needle,len2)==0){
return (char * )haystack;
}
++haystack;
}
return NULL;
}
10、Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
不能用乘法,出发和mod操作来进行除法。。。
那就是位操作了,移位。
class Solution {
public:
/*被除数,除数
2147483647, 2 超时
这个题目好多东西需要考虑
负数问题,以及会不会超过最大值long的问题
终于accpet了
为什么这么粗心啊,最大数,最小数,以及两个位不相同
*/
int divide(int dividend, int divisor) {
bool notpositive = (dividend<0)^(divisor<0);
unsigned long tdividend = abs(dividend);
unsigned long tdivisor = abs(divisor);
if(tdivisor==1||tdividend==0){
return notpositive?0-tdividend:tdividend;
}
if(tdividend<tdivisor){
return 0;
}
if(tdividend==tdivisor){
return divisor!=dividend?-1:1;
}
unsigned long tmp = tdivisor;//被除数
int multi = 1;
unsigned long tmpdivid = tdividend;//除数
while(tmpdivid>(tmp<<1)&&(tmp<<1)<INT_MAX){
multi = multi<<1;
tmp = tmp<<1;
}
//循环相减
int ret = 0;
while(tmp>=tdivisor){
if(tdividend<=0){
break;
}
while(tdividend<tmp){
tmp = tmp >> 1;
multi = multi >> 1;
}
if(tmp<tdivisor){//tmp的基底是divisor,被除数
break;
}
tdividend -= tmp;
ret += multi;
}
return notpositive?0-ret:ret;
}
};
class Solution {
public:
/*被除数,除数
2147483647, 2 超时
这个题目好多东西需要考虑
负数问题,以及会不会超过最大值long的问题
终于accpet了
为什么这么粗心啊,最大数,最小数,以及两个位不相同
*/
int divide(int dividend, int divisor) {
bool notpositive = (dividend<0)^(divisor<0);
unsigned long tdividend = abs(dividend);
unsigned long tdivisor = abs(divisor);
if(tdivisor==1||tdividend==0){
return notpositive?0-tdividend:tdividend;
}
if(tdividend<tdivisor){
return 0;
}
if(tdividend==tdivisor){
return divisor!=dividend?-1:1;
}
unsigned long tmp = tdivisor;//被除数
int multi = 1;
unsigned long tmpdivid = tdividend;//除数
while(tmpdivid>(tmp<<1)&&(tmp<<1)<INT_MAX){
multi = multi<<1;
tmp = tmp<<1;
}
//循环相减
int ret = 0;
while(tmp>=tdivisor){
if(tdividend<=0){
break;
}
while(tdividend<tmp){
tmp = tmp >> 1;
multi = multi >> 1;
}
if(tmp<tdivisor){//tmp的基底是divisor,被除数
break;
}
tdividend -= tmp;
ret += multi;
}
return notpositive?0-ret:ret;
}
};