面试常考算法题总结(一)

原创 2016年08月29日 23:09:40

题目链接:面试常考算法题(一)

题目1:请把一张窄纸条竖着放在桌上,然后从纸条的下边向上对折,压出折痕后再展开。此时有1条折痕,突起的一面向指向纸条的背面,这条折痕叫做“下”折痕;突起的向指向纸条正面的折痕叫做“上”折痕。如果每次都从下边向上进行对折,对折N次。请从上到下计算出所有折痕的朝向。给定折的次数n,请返回从上到下的折痕的数组,若为下折痕则对应元素为"down",若为上折痕则为"up"。

测试样例:
1
返回:["down"]
分析:这题首先容易想到的是找规律,首先我们先对前几项结果进行观察:
n = 1, size = 1: "down",
n = 2, size = 3:  "down""down""up"
n = 3, size = 7:  "down""down""up""down""down""up""up"
可以观察到每次迭代的时候,数组的新size是前面size的2倍加上1,即size = 2*size+1,
前面的部分和上一组完全相同,最中间的值恒为"down",后半部分字节将前面的值翻转
并取反即可得到。talk is cheap,show me the code:
class FoldPaper {
public:
    vector<string> foldPaper(int n) {
        vector<string> res;
        if(n==1)
            res.push_back("down");
        else{
            vector<string> v = foldPaper(n-1);
            for(int i = 0;i<v.size();++i){
                res.push_back(v[i]);
            }
            res.push_back("down");
            reverse(v.begin(),v.end());
            for(int i = 0;i<v.size();++i){
                if(v[i]=="down")
                	res.push_back("up");
                else
                    res.push_back("down");
            }
        }
        return res;
    }
};

另一条思路是转化为二叉树的中序遍历,构建一颗二叉树,根节点是down,左子树的根是down,右子树的根节点是up。可以构造一个满二叉树,talk is cheap,show me the code:

class FoldPaper {
public:
    vector<string> foldPaper(int n) {
        // write code here
        vector<string> vec;
        pushs(vec,n,"down");
        return vec;
    }
    //中序遍历程序
    void pushs(vector<string> &vec,int n,string str)
    {
        if(n>0)
        {
            pushs(vec,n-1,"down");
            vec.push_back(str);
            pushs(vec,n-1,"up");
        }
    }
};
更多讨论见折纸问题

题目2:对于一个矩阵,请设计一个算法从左上角(mat[0][0])开始,顺时针打印矩阵元素。给定int矩阵mat,以及它的维数nxm,请返回一个数组,数组中的元素为矩阵元素的顺时针输出。
测试样例:
[[1,2],[3,4]],2,2
返回:[1,2,4,3]

分析:基本思路是不管简化矩阵,先顺时针打印矩阵外围的一圈,然后不断缩小矩阵即可,最后讨论一下只有一行或者一列的情形,talk is cheap,show me the code:

class Printer {
public:
    void clockwisePrint(const vector<vector<int>> &mat,vector<int> &res,int row1,int col1,int row2,int col2){
		//左上角(row1,col1)右下角(row2,col2)
        int i = row1,j=col1;
        while(j<=col2)   //上一行向右
            res.push_back(mat[i][j++]);
        --j,++i;
        while(i<=row2)   //右一行向下
            res.push_back(mat[i++][j]);
        --i,--j;
        if(row1 == row2 || col1 == col2) //只又一列或一行时,不向左,也不向上
            return;     
        while(j>=col1)  //下一行向左
            res.push_back(mat[i][j--]);
        ++j,--i;           
        while(i>row1)   //左一行向上,不打印左上角
            res.push_back(mat[i--][j]);           
    }
    vector<int> clockwisePrint(vector<vector<int> > mat, int n, int m) {
        int row1,row2,col1,col2;
        std::vector<int> res;
        for(row1 = 0,col1=0,row2=n-1,col2=m-1;row1<=row2 && col1<=col2;row1++,col1++,row2--,col2--)
            clockwisePrint(mat,res,row1,col1,row2,col2);
        return res;
    }
};

题目3:有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵,保证N小于等于300。

测试样例:
[[1,2,3],[4,5,6],[7,8,9]],3
返回:[[7,4,1],[8,5,2],[9,6,3]]

分析:找出旋转后的矩阵每个元素的位置在原来矩阵中对应位置之间的关系即可,talk is cheap,show me the code:

class Rotate {
public:
    vector<vector<int> > rotateMatrix(vector<vector<int> > mat, int n) {
        vector<vector<int> > vmat(n,vector<int>(n,0));
        for(int i = 0;i<n;++i){
            for(int j = 0;j<n;++j)
                vmat[i][j] = mat[n-1-j][i];
        }
        return vmat;
    }
};


题目4:对于一个矩阵,请设计一个算法,将元素按“之”字形打印。具体见样例。给定一个整数矩阵mat,以及他的维数nxm,请返回一个数组,其中元素依次为打印的数字。
测试样例:
[[1,2,3],[4,5,6],[7,8,9],[10,11,12]],4,3
返回:[1,2,3,6,5,4,7,8,9,12,11,10]

分析:行是奇数从左到右打印,行是偶数从右到左打印,talk is cheap,show me the code:

class Printer {
public:
    vector<int> printMatrix(vector<vector<int> > mat, int n, int m) {
        vector<int> res;
        int i = 0;
        while(i<n){
            if(i%2==0){
                for(int j = 0;j<m;++j)
                    res.push_back(mat[i][j]);
            }
            else{
                for(int j = m-1;j>=0;--j)
                    res.push_back(mat[i][j]);
            }
            ++i;
        }
        return res;
    }
};


题目5:对于一个字符串,和字符串中的某一位置,请设计一个算法,将包括i位置在内的左侧部分移动到右边,将右侧部分移动到左边。给定字符串A和它的长度n以及特定位置p,请返回旋转后的结果。
测试样例:
"ABCDEFGH",8,4
返回:"FGHABCDE"
分析:参考博客字符串移位的解题技巧。talk is cheap,show me the code:

class StringRotation {
public:
    string rotateString(string A, int n, int p) {
        return A.substr(p+1)+A.substr(0,p+1); 
    }
};


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

面试常考算法题总结(二)

题目链接:试卷1和试卷2。 题目1:对于一个无序数组A,请设计一个算法,求出需要排序的最短子数组的长度。给定一个整数数组A及它的大小n,请返回最短子数组的长度。 测试样例: [1,5,3,4,2...

JAVA实现单向链表反转

本片内容代码反转算法为转载!!上一篇《Java实现单向链表反转》中存在一个last是从前往后反转的。本片文章要实现的是从后往前反转。大体思路差不多。就是在临时变量.cur,pre的替换保存花费了些心思...
  • djx0226
  • djx0226
  • 2013年06月04日 03:11
  • 985

笔试面试常考排序算法总结

在笔试面试的过程中,常常会考察一下常见的几种排序算法,包括冒泡排序,插入排序,希尔排序,直接选择排序,归并排序,快速排序,堆排序等7种排序算法,下面将分别进行讲解。另外,我自己在学习这几种算法过程中,...
  • hmxz2nn
  • hmxz2nn
  • 2016年11月11日 20:47
  • 489

牛客面试常考算法题精讲部分题目c/c++代码

最近在看牛客网左程云老师讲解常考面试题(http://www.nowcoder.com/live/courses),感觉讲的非常好,但是给的代码都是java的,故我这里用c++自己写了一遍,作为一个记...

面试常考算法题 局部最小 求二叉树结点 求两个数组中所有数的上中位数 两个数组的所有数中第K小的数

定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0] 给定无序数组arr,已知arr中任意两个相邻的数都不相等,写一个函数,只需返回arr中任...

Java实现面试常考的算法

Java实现面试常考的算法 查找算法 排序算法 插入排序 选择排序 冒泡排序 快速排序Java实现面试常考的算法 我自己总结了几个平时面试问得一些算法题, 都是非常非常基础的问题. 查找算法 ...

面试常考之排序算法

总结一下面试常常遇到的基础排序算法(默认升序),方便复习: 1.选择排序 思想:每一趟选出最小值 复杂度分析:最坏情况O(n^2),最好情况O(n^2),平均情况O(n^2),额外空间O(1...
  • rido_
  • rido_
  • 2017年06月16日 17:48
  • 79

面试常考的常用数据结构与算法

数据结构与算法,这个部分的内容其实是十分的庞大,要想都覆盖到不太容易。在校学习阶段我们可能需要对每种结构,每种算法都学习,但是找工作笔试或者面试的时候,要在很短的时间内考察一个人这方面的能力,把每种结...

c/c++ 面试常考算法

二分查找算法int bfind(int *a,int len,int val) { int m=len/2; int l=0; int r=len; whil...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:面试常考算法题总结(一)
举报原因:
原因补充:

(最多只允许输入30个字)