找工作--笔试面试--准备9

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

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 (a1a2, … , 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];
        }
    }
};

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 (a1a2, … , 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].

找到一个区间,其实这个应该放在,专门的二叉数的那个里面。。。

二分查找,然后找到target,然后向两边进行扩散查找,不能保证是logn
TODO

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

存在返回index,不存在返回应该插入的位置。

我用的是从后往前遍历,然后这样的话,复杂度是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;
    }
};

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

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

感谢水中的鱼,看图就可以了。。。


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--]);
        }
        
    }
};

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.

华为有一道机试题和这个差不多。栈,stack

有一些不同,这个是求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
类似于智力题目,但是只要一直往下写就可以了。一开始没有任何思路,后来想了想,其实堆栈应该也可是可以的。

上一个数用堆栈,下一个数存储在队列里面,然后迭代进行计算。

这里用了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;
    }
};


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值