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

1、Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

 寻找最短路径,移动只能向下或者向右,动态规划的思想。申请一个m*n的数组,保存0,0到达该点的路径最短长度。

int minPathSum(vector<vector<int> > &grid) {
        int m = grid.size();
        if(m==0){
            return 0;
        }
        int n = grid[0].size();
        if(n==0){
            return 0;
        }
        vector<vector<int>> vec(m,vector<int>(n));
        vec[0][0] = grid[0][0];
        for(int i = 1;i<m;i++){
            vec[i][0] = vec[i-1][0]+grid[i][0];
        }
        for(int j = 1;j<n;j++){
            vec[0][j] = vec[0][j-1] + grid[0][j];
        }
        for(int i = 1;i<m;i++){
            for(int j = 1;j<n;j++){
                vec[i][j] = vec[i-1][j]>vec[i][j-1]?vec[i][j-1]:vec[i-1][j];
                vec[i][j] += grid[i][j]; 
            }
        }
        return vec[m-1][n-1];
    }
2、Add Binary

Given two binary strings, return their sum (also a binary string).

For example,
a = "11"
b = "1"
Return "100".

要考虑的问题,字符串太长。

本来是一道简单的题目,没想到当时我写了这么多代码,其实是可以直接string的append方法,然后reverse方法进行reverse的。我用的栈存储,然后提取出来,是麻烦了一些。。。

string addBinary(string a, string b) {
        int lena = a.size();
        int lenb = b.size();
        if(lena == 0){
            return b;
        }
        if(lenb == 0){
            return a;
        }
        bool add = false;
        stack<char> ret;
        while(lena>0&&lenb>0){
            
            if(a[lena-1]=='1'&&b[lenb-1]=='1'&&add){
                add = true;
                ret.push('1');
            }
            else if(a[lena-1]=='1'&&b[lenb-1]=='1'&&!add){
                add = true;
                ret.push('0');
            }
            else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&!add){
                add = false;
                ret.push('0');
            }
            else if(a[lena-1]=='0'&&b[lenb-1]=='0'&&add){
                add = false;
                ret.push('1');
            }
            else if((a[lena-1]=='1'^b[lenb-1]=='1')&&add){
                add = true;
                ret.push('0');
            }
            else{
                add = false;
                ret.push('1');
            }
            lena--;
            lenb--;
        }
        while(lena>0){
            if(a[lena-1]=='1'&&add){
                add = true;
                ret.push('0');
            }
            else if((a[lena-1]=='1'&&!add)||(a[lena-1]=='0'&&add)){
                add = false;
                ret.push('1');
            }
            else{
                add=false;
                ret.push('0');
            }
            lena--;
        }
        while(lenb>0){
            if(b[lenb-1]=='1'&&add){
                add = true;
                ret.push('0');
            }
            else if((b[lenb-1]=='1'&&!add)||(b[lenb-1]=='0'&&add)){
                add = false;
                ret.push('1');
            }
            else{
                add=false;
                ret.push('0');
            }
            lenb--;
        }
        if(add){
            ret.push('1');
        }
        string temp = "";
        while(!ret.empty()){
            temp += ret.top();
            ret.pop();
        }
        return temp;
    }
3、Valid Number

Validate if a given string is numeric.

Some examples:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false
"2e10" => true

Note: It is intended for the problem statement to be ambiguous. You should gather all requirements up front before implementing one.

情况非常多

在字符串之前有空格需要去掉,科学表示法也是正确的,小数也是正确的,多个小数点问题。

这道题目,我是参考的网上的方案,具体的方案,在这里。

用了有限状态机,然后对于每个字符有相关的转换关系。

有限状态机 TODO

http://www.cnblogs.com/chasuner/p/validNumber.html

http://haiyangxu.github.io/posts/2014/2014-05-06-LeetCode-Valid-Number.html

enum Op{
    Operator, //0
    Digit, // 1
    E, // 2
    Dot, //3
    Space,// 4
    Invalid
};
int table[][5] = {
    {1,2,-1,8,-1},
    {-1,2,-1,8,-1},
    {-1,2,4,3,-1},
    {-1,7,4,-1,-1},
    {5,6,-1,-1,-1},
    {-1,6,-1,-1,-1},
    {-1,6,-1,-1,-1},
    {-1,7,4,-1,-1},
    {-1,9,-1,-1,-1},
    {-1,9,4,-1,-1}

};
class Solution {
public:
    bool trim(string& s) {
        int start = 0;
        int end = s.size() - 1;
        while(start <= end && s[start] == ' ') start++;
        while(end >= 0 && s[end] == ' ') end--;
        if(end >= start) s = s.substr(start , end - start + 1);
        else return false;
        return true;
    }
    Op getOp(char ch) {
        if(ch == '+' || ch == '-') return Operator;
        if(ch >= '0' && ch <= '9') return Digit;
        if(ch == 'e') return E;
        if(ch == '.') return Dot;
        if(ch == ' ') return Space;
        return Invalid;
    }
    bool isNumber(const char *s) {
        string str = s;
        if(!trim(str)) return false;
        int pos = 0;
        int size = str.size();
        int state = 0;
        while(pos < size) {
            char ch = str[pos];
            Op x = getOp(ch);
            if(x == Invalid) return false;
            state = table[state][(int)x];
            if(state == -1) return false;
            pos++;
        }
        return state == 2 || state == 6  || state == 7 || state == 3 || state == 9;
    }
};
4、

Plus One

 

Given a non-negative number represented as an array of digits, plus one to the number.

The digits are stored such that the most significant digit is at the head of the list.

用数组表示的一个数,然后加一,考虑的情况如果都是9的情况,或者说大部分是9的情况。

vector<int> plusOne(vector<int> &digits) {
        int i;
        for(i = digits.size() - 1;i >= 0;--i){
            if(digits[i] != 9){
                ++digits[i];
                return digits;
            }
            else {
                digits[i] = 0;
            }
        }
        //各位全是9
        if(i < 0) {
            digits.insert(digits.begin(),1);//头部插入1
        }
        return digits;
    }

5、Text Justification

 

Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified.

You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pad extra spaces ' ' when necessary so that each line has exactly Lcharacters.

Extra spaces between words should be distributed as evenly as possible. If the number of spaces on a line do not divide evenly between words, the empty slots on the left will be assigned more spaces than the slots on the right.

For the last line of text, it should be left justified and no extra space is inserted between words.

For example,
words["This", "is", "an", "example", "of", "text", "justification."]
L16.

Return the formatted lines as:

[
   "This    is    an",
   "example  of text",
   "justification.  "
]

Note: Each word is guaranteed not to exceed L in length.

click to show corner cases.

Corner Cases:

  • A line other than the last line might contain only one word. What should you do in this case?
    In this case, that line should be left-justified.
这个在word软件进行排版的时候是特别有用的。

class Solution {
public:
/**
 * 字符串处理,贪心,平均空格,最后一行的处理
 * */
   vector<string> fullJustify(vector<string> &words, int L) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        vector<string>res;
        int len = words.size(), i = 0;
        while(i < len)
        {
            //if(words[i].size() == 0){i++; continue;}
            int rowlen = 0, j = i;
            while(j < len && rowlen + words[j].size() <= L)
                rowlen += (words[j++].size() + 1);
            //j-i是该行放入单词的数目
            if(j - i == 1)
            {//处理放入一个单词的特殊情况
                res.push_back(words[i]);
                addSpace(res.back(), L - words[i].size());
                i = j; continue;
            }
            //charaLen是当前行字母总长度
            int charaLen = rowlen - (j - i);
            //平均每个单词后的空格,j < len 表示不是最后一行
            int meanSpace = j < len ? (L - charaLen) / (j - i - 1) : 1;
            //多余的空格
            int leftSpace = j < len ? (L - charaLen) % (j - i - 1) : L - charaLen - (j - i -1);
            string tmp;
            for(int k = i; k < j - 1; k++)
            {
                tmp += words[k];
                addSpace(tmp, meanSpace);
                if(j < len && leftSpace > 0)
                {
                    tmp.push_back(' ');
                    leftSpace--;
                }
            }
            tmp += words[j - 1];//放入最后一个单词
            if(leftSpace > 0)addSpace(tmp, leftSpace); //对最后一行
            res.push_back(tmp);
            i = j;
        }
        return res;
    }
     
    void addSpace(string &s, int count)
    {
        for(int i = 1; i <= count; i++)
            s.push_back(' ');
    }
};

6、Sqrt(x)

Implement int sqrt(int x).

Compute and return the square root of x.

sqrt实现,这里用了二分查找的方式,在0,x+1/2之间进行计算

int sqrt(int x) {
        if(x<=0){
            return NULL;
        }
        unsigned long long left = 0;
        unsigned long long right = (x+1)/2;
        unsigned long long mid = 0;
        
        while(left<right){
            mid = (right + left)/2;
            unsigned long long value = mid*mid;
            if(value == x){
                return mid;
            }
            else if(value > x){
                right = mid - 1;
                
            }
            else{
                
                left = mid + 1;
            }
            
        }
        if(right*right>x){
            return right - 1;
            
        }
        else{
            return right;
        }
        
    }

7、Climbing Stairs

 
 

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

类似青蛙跳,动态规划。

int climbStairs(int n) {
        if(n==1){
            return 1;
        }
        int first = 1;
        int second = 1;
        int i = 1;
        int ret = 0;
        while(i<n){
            ret = first + second;
            first = second;
            second = ret;
            i++;
        }
        return ret;
    }
8、Unique Paths&&

Unique Paths II

 

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

Above is a 3 x 7 grid. How many possible unique paths are there?

Note: m and n will be at most 100.

动态规划

int uniquePaths(int m, int n) {
        if(m==0||n==0){
            return 0;
        }
        vector<vector<int>> vec(m,vector<int>(n));
        for(int i =0;i<m;i++){
            vec[i][n-1] = 1;
        }
        for(int i=0;i<n;i++){
            vec[m-1][i] = 1;
        }
        for(int i=m-2;i>=0;i--){
            for(int j = n-2;j>=0;j--){
                vec[i][j] = vec[i+1][j]+vec[i][j+1];
            }
        }
        return vec[0][0];
    }

Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is 2.

Note: m and n will be at most 100.

还是继续动态规划,只是在1的位置不进行加就可以了。

首先赋初值,赋初值的时候首先将和目标结点同一行和同一列的数值进行赋值。

int uniquePathsWithObstacles(vector<vector<int> > &obstacleGrid) {
        int m = obstacleGrid.size();
        if(m==0){
            return 0;
        }
        int n = obstacleGrid[0].size();
        if(n==0){
            return 0;
        }
        vector<vector<int>> vec(m,vector<int>(n));
        bool isobs = false;
        for(int i =m-1;i>=0;i--){
            if(obstacleGrid[i][n-1]==1||isobs){
                vec[i][n-1] = 0;
                isobs = true;
            }
            else
                vec[i][n-1] = 1;
        }
        isobs = false;
        for(int i=n-1;i>=0;i--){
            if(obstacleGrid[m-1][i]==1||isobs){
                vec[m-1][i] = 0;
                isobs = true;
            }
            else
                vec[m-1][i] = 1;
        }
        if(m==1||n==1){
            return vec[0][0];
        }
        for(int i=m-2;i>=0;i--){
            for(int j = n-2;j>=0;j--){
                if(obstacleGrid[i][j]==1){
                    vec[i][j] = 0;
                }
                else{
                    vec[i][j] = vec[i+1][j]+vec[i][j+1];
                }
                
            }
        }
        return vec[0][0];
    }

9、Permutation Sequence

 

The set [1,2,3,…,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order,
We get the following sequence (ie, for n = 3):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

主要是对n的全排列进行计数,然后对n-0的各个全排列进行技术

从最高位开始一个一个确认该位是什么,利用了k模i的全排列的个数。

class Solution {
public:
/*
这个题耗费的时间比较多
主要出现问题在,k需要先进行-1操作,这样保证初始是0,及第一个元素
比如,2,2的例子
12
21
如果是2
如果不减一的话,那就得到倍数是2,那就是第三个数,这是错误的
*/
    string getPermutation(int n, int k) {
        string ret;
        vector<int> vec(n-1);
        map<int,int> nmap;
        map<int,int> vmap;
        int num = 0;
        int i = 0;
        for(i=1;i<=n;i++){
            vmap[i]=1;
        }
        i = n-1;
		k--;
        while(i>0){
            int x = getvalue(i);
            nmap[i] = k/x;//第i位需要第几个元素
            k = k%x;
            i--;
        }
        map<int,int>::iterator iter;
        for(i = n-1;i>0;i--){
            if(nmap[i]==0){
				ret += '0'+vmap.begin()->first;//添加该首个元素
				iter = vmap.begin();
				vmap.erase(iter);
            }
			else{
				iter = vmap.begin();//确认是第几个元素
				for(int j=0;j<nmap[i];j++){
					iter++;
				}
				ret += '0'+iter->first;
				vmap.erase(iter);
			}
        }
        ret += '0' + vmap.begin()->first;
		return ret;
    }
    int getvalue(int n){
        if(n == 1||n==0){
            return 1;
        }else{
            return n*getvalue(n-1);
        }
    }
};

10、Spiral Matrix I II

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

You should return [1,2,3,6,9,8,7,4,5].

从左到右,从上到下,从右到左,从下到上。仔细一下

vector<int> spiralOrder(vector<vector<int> > &matrix) {
        vector<int> result;  
        if (matrix.empty()) return result;  
        int beginX = 0, endX = matrix[0].size() - 1;  
        int beginY = 0, endY = matrix.size() - 1;  
        while (true) {  
            // From left to right  
            for (int i = beginX; i <= endX; ++i)  
                result.push_back(matrix[beginY][i]);  
            if (++beginY > endY) break;  
            // From top down  
            for (int i = beginY; i <= endY; ++i)  
                result.push_back(matrix[i][endX]);  
            if (beginX > --endX) break;  
            // From right to left  
            for (int i = endX; i >= beginX; --i)  
                result.push_back(matrix[endY][i]);  
            if (beginY > --endY) break;  
            // From bottom up  
            for (int i = endY; i >= beginY; --i)  
                result.push_back(matrix[i][beginX]);  
            if (++beginX > endX) break;  
        }  
        return result;  
    }

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.

For example,
Given n = 3,

You should return the following matrix:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]
我个人觉得1-n^2这个比较简单。

class Solution {
public:
    vector<vector<int> > generateMatrix(int n) {
        vector<vector<int>> vec(n,vector<int>(n));
        int top = 0;
        int buttom = n-1;
        int left = 0;
        int right = n-1;
        int value = 1;
        while(top<buttom){
            for(int i=left;i<right;i++){
                vec[top][i]=value++;
            }
            for(int i = top;i<buttom;i++){
                vec[i][right] = value++;
            }
            for(int i = right;i>left;i--){
                vec[buttom][i] = value++;
            }
            for(int i = buttom;i>top;i--){
                vec[i][left] = value++;
            }
            top++;
            buttom--;
            left++;
            right--;
        }
        if(top == buttom){
            vec[top][buttom]=value;
        }
        return vec;
    }
};










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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值