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

1、N-Queens I&&II

The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.


Given an integer n, return all distinct solutions to the n-queens puzzle.

Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.

For example,
There exist two distinct solutions to the 4-queens puzzle:

[
 [".Q..",  // Solution 1
  "...Q",
  "Q...",
  "..Q."],

 ["..Q.",  // Solution 2
  "Q...",
  "...Q",
  ".Q.."]
]
回溯法,将所有结果输出

class Solution {
public:
    vector<vector<string> > res;
    //vector<vector<string>> res;
    void helper(vector<string> &cur, int row)
    {
        if(row == cur.size())
        {
            res.push_back(cur);
            return;
        }
        for(int col = 0; col < cur.size(); col++)
            if(isValid(cur, row, col))
            {
                cur[row][col] = 'Q';
                helper(cur, row+1);
                cur[row][col] = '.';
            }
    }
    //判断在cur[row][col]位置放一个皇后,是否是合法的状态
    //已经保证了每行一个皇后,只需要判断列是否合法以及对角线是否合法。
    bool isValid(vector<string> &cur, int row, int col)
    {
        //列
        for(int i = 0; i < row; i++)
            if(cur[i][col] == 'Q')return false;
        //左对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
        for(int i = row-1, j=col-1; i >= 0 && j >= 0; i--,j--)
            if(cur[i][j] == 'Q')return false;
        //右对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
        for(int i = row-1, j=col+1; i >= 0 && j < cur.size(); i--,j++)
            if(cur[i][j] == 'Q')return false;
        return true;
    }
    vector<vector<string> > solveNQueens(int n) {
        vector<string> ret(n, string(n,'.'));
        //helper(ret, 0);
        dfs(ret,0);
        return res;
    }
    
    bool isvalid(vector<string> &cur,int row,int col){
        for(int i = 0;i<row;i++){
            if(cur[i][col]=='Q'){
                return false;
            }
        }
        for(int i = row-1,j = col-1;i>=0&&j>=0;i--,j--){
            if(cur[i][j]=='Q'){
                return false;
            }
        }
        for(int i=row-1,j = col+1;i>=0&&j<cur.size();i--,j++){
            if(cur[i][j]=='Q'){
                return false;
            }
        }
        return true;
    }
    void dfs(vector<string> &cur,int row){
        if(row == cur.size()){
            res.push_back(cur);
            return;
        }
        for(int col = 0;col<cur.size();col++){
            if(isvalid(cur,row,col)){
                cur[row][col]='Q';
                dfs(cur,row+1);
                cur[row][col] = '.';
            }
        }
    }
};

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

原理相似,count++

class Solution {
public:
    int value;
    int totalNQueens(int n) {
        value = 0;
        vector<string> ret(n, string(n,'.'));
        dfs(ret,0);
        return value;
    }
    bool isvalid(vector<string> &cur,int row,int col){
        for(int i = 0;i<row;i++){
            if(cur[i][col]=='Q'){
                return false;
            }
        }
        for(int i = row-1,j = col-1;i>=0&&j>=0;i--,j--){
            if(cur[i][j]=='Q'){
                return false;
            }
        }
        for(int i=row-1,j = col+1;i>=0&&j<cur.size();i--,j++){
            if(cur[i][j]=='Q'){
                return false;
            }
        }
        return true;
    }
    void dfs(vector<string> &cur,int row){
        if(row == cur.size()){
            value++;
            return;
        }
        for(int col = 0;col<cur.size();col++){
            if(isvalid(cur,row,col)){
                cur[row][col]='Q';
                dfs(cur,row+1);
                cur[row][col] = '.';
            }
        }
    }
};

2、Length of Last Word

 

Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.

If the last word does not exist, return 0.

Note: A word is defined as a character sequence consists of non-space characters only.

For example, 
Given s = "Hello World",
return 5.

int lengthOfLastWord(const char *s) {
        string str = s;
        int len = str.size();
        if(len==0){
            return 0;
        }
        int wlen = 0;
        len--;
        while(len>=0&&str[len]==' '){
            len--;
        }
        while(len>=0&&str[len]!=' '){
            wlen++;
            len--;
        }
        return wlen;
    }

3、Maximum Subarray

 

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.

click to show more practice.

More practice:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

最大子序列的和


int maxSubArray(int A[], int n) {
        int sum = A[0], max = A[0];  
        for (int i = 1; i < n; i++) {  
            sum = sum < 0 ? A[i] : sum + A[i];  
            max = sum > max ? sum : max;  
        }  
        return max;  
    }

4、Jump Game

 

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

还是动态规划,利用的方法是记录最远可以到达的地方,然后每次访问一个点的时候动态更新。

class Solution {
public:
/*
第二种方案,增加一个从0位置所能到的最远距离 maxdis
如果0可到达当前位置,而且当前位置可以到达n-1,返回true
如果0不可到达当前位置,而且当前位置不能到达n-1,返回false
其他情况几率maxdis
*/
    bool canJump(int A[], int n) {
        if(n==0||A==NULL){
            return false;
        }
        if(A[0]>=n-1){
            return true;
        }
        int maxdis = A[0];
        if(maxdis==0){
            return false;
        }
        for(int i = 1;i<n-1;i++){
            if(maxdis>=i&&A[i]+i>=n-1){
                return true;
            }
            if(maxdis<=i&&A[i]==0){
                return false;
            }
            if(i+A[i]>maxdis){
                maxdis = i+A[i];
            }
        }
        return false;
    }
};

5、Merge Intervals && 

Insert Interval

 

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].

区间的合并问题,一开始我是觉得很难的,不过看了别人的思路,总结一下方法:

首先根据start进行排序,然后对排序的数组进行遍历,当发现当前的数组的start在上一个数组范围之内的话,则本数组需要重新定义长度。

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
/*
这个很赞
先排序
然后合并,合并的时候通过对另外构造一个vector,然后判断如果start在上一个区间中间,则这个区间重新定义长度
*/
    static bool comp(Interval a, Interval b)
    {
        return a.start < b.start;
    }
    vector<Interval> merge(vector<Interval> &intervals) {
        if(intervals.empty())return intervals;
        sort(intervals.begin(), intervals.end(), comp);
        vector<Interval> res;
        res.push_back(intervals[0]);
        for(int i = 1; i < intervals.size(); i++)
        {
            Interval &p = res.back();
            if(intervals[i].start > p.end)res.push_back(intervals[i]);
            else if(intervals[i].end > p.end)p.end = intervals[i].end;
        }
        return res;
    }
    
};
这个和上一个是一个类型的题目。

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].

这两个题目都好赞,根据比较start和end来插入数据。

class Solution {
public:
    vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) {
        vector<Interval> ret;
        int sta = newInterval.start;
        int end = newInterval.end;
        int i = 0;
        for(;i<intervals.size()&&sta>intervals[i].end;i++){
            ret.push_back(intervals[i]);
        }
        if(i<intervals.size()){
            sta = min(sta,intervals[i].start);
        }
        for (; i<intervals.size() && end >= intervals[i].start; i++)  
            end = max(end, intervals[i].end); 
        ret.push_back(Interval(sta, end)); 
        ret.insert(ret.end(), intervals.begin()+i, intervals.end());  
        return ret;
    }
};
6、Rotate Image

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Follow up:
Could you do this in-place?

方法一、申请一个n*n的数组,然后将原始数组存入。这是最快速的方案。

方法二,这个是一个数学原理方案,原理主要是先左上角和右下角进行对折互换,然后再沿中线进行对折兑换,就可以了。

class Solution {
public:
/*先延对角线翻转,然后中线翻转
http://fisherlei.blogspot.sg/2013/01/leetcode-rotate-image.html
*/
    void rotate(vector<vector<int> > &matrix) {
        int n = matrix.size();
        if(n<=1){
            return;
        }
        for(int i = 0;i<n;i++){
            for(int j = 0;j<n-i;j++){
                swap(matrix[i][j],matrix[n-1-j][n-1-i]);
            }
        }
        for(int i = 0;i<n/2;i++){
            for(int j = 0;j<n;j++){
                swap(matrix[i][j],matrix[n-1-i][j]);
            }
        }
    }
};

7、Anagrams

 

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

For example:

Input:  ["tea","and","ate","eat","den"]

Output:   ["tea","ate","eat"]

原理:读入一个string,然后排序,将排序好的string 添加如map

然后读入下一个string,同样排序,如果存在,则添加如vector里面。


vector<string> anagrams(vector<string> &strs) {
        vector<string> ret;
        if(strs.size()<=1){
            return ret;
        }
        map<string,int> vec;
        for(int i=0;i<strs.size();i++){
            string s = strs[i];
            sort(s.begin(),s.end());
            if(vec.find(s)==vec.end()){
                vec.insert(make_pair(s, i));
            }
            else{
                if(vec[s]>=0){
                    ret.push_back(strs[vec[s]]);
                    vec[s]=-1;
                }
                ret.push_back(strs[i]);
            }
        }
    }
8、First Missing Positive

Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.

这个题目,理解提议很重要,题目要求找到第一个丢失的正数。所以可以排除掉所有的负数。

可以考虑将申请n的空间,然后将,1.2.等正数按顺序存入数组,这样就可以发现失去的第一个正整数。
题目要求的是constant space 我们可以利用传入的数组,我们将数组进行排序,最快的排序也是nlogn,所以这个方法不行,
既然是n,我们可以一个一个字符进行遍历,然后如果是大于0的数,我们存入他的位置。
class Solution {
public:
/*
注意几个特别的字眼,正整数,所以其他的不用管,连续的正整数在哪里断开了,是问题关键,将正整数存入其数值所代表的位置
*/
    int firstMissingPositive(int A[], int n) {
        int i = 0;
        for(;i<n;){
            if(A[i]<=0||A[i]==i+1||A[i]>n||A[i]==A[A[i]-1]){
                i++;
            }
            else{
                swap(A[i],A[A[i]-1]);
            }
        }
        for(i = 0;i<n;i++){
            if(i+1!=A[i]){
                break;
            }
        }
        return i+1;
    }
    
};
9、Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.


The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

原理是,从左到右,从右到左,分别计算当前bar的左边和右边最大值,这样就可以计算出当前bar可以存储多少水量。
class Solution {
public:
     int trap(int A[], int n) {
        //no way to contain any water
        if(n <= 2) return 0;
        
        //1. first run to calculate the heiest bar on the left of each bar
        int *lmh = new int[n];//for the most height on the left
        lmh[0] = 0;
        int maxh = A[0];
        for(int i = 1; i < n; ++i) {
            lmh[i] = maxh;
            if(maxh < A[i]) maxh = A[i];
        }
        int trapped = 0;
        
        //2. second run from right to left, 
        // caculate the highest bar on the right of each bar
        // and calculate the trapped water simutaniously
        maxh = A[n-1];
        for(int i = n - 2; i > 0; --i) {
            int left = lmh[i];
            int right = maxh;
            int container = min(left,right);
            if(container > A[i]) {
                trapped += container - A[i];
            }
            if(maxh < A[i]) maxh = A[i];
        }
        delete lmh;
        return trapped;
    }
};

10、Multiply Strings

 

Given two numbers represented as strings, return multiplication of the numbers as a string.

Note: The numbers can be arbitrarily large and are non-negative.

字符串的相乘,本科的时候有一次实验是做大整数相乘
典型的乘法,然后将数据添加到一个数组中,最后对数组进行进位。
int data[100000];
    string multiply(string num1, string num2) {
        reverse(num1.begin(),num1.end());
        reverse(num2.begin(),num2.end());
        memset(data,0,sizeof(data));
        int len1 = num1.size();
        int len2 = num2.size();
        for(int i = 0;i<len1;i++){
            for(int j = 0;j<len2;j++){
                data[i+j] += (num1[i]-'0')*(num2[j]-'0');
            }
        }
        int p,temp;
        p = 0;
        int i = 0;
        while(i<len1+len2||p!=0){
            temp = data[i]+p;
            data[i] = temp%10;
            p = temp/10;
            i++;
        }
        string result;
        bool flag = 0;
        for(;i>=0;i--){
            if(flag == 0&&data[i]==0){
                continue;
            }
            else{
                flag = 1;
                result += (char)(data[i]+'0');
            }
        }
        if(flag == 0){
            return "0";
        }
        else{
            return result;
            
        }
    }







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值