T1 二维部分有序数组查找 ☆

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

由于矩阵部分有序,向上数字递减,向右数字递增:

  1. 目标数字只会出现在行首小于该数的行中
  2. 遍历行i ,若列j 对应的元素大于目标,那么在前 i-1 行,目标只会出现在 j列及以后。

因此,可以从左下角开始查找。目标比左下角数字小时,上移;当要目标比左下角数字大时,右移。

搜索的路线是阶梯状,复杂度为O(行数+列数)。

class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int nrows = array.size();
int ncols = array[0].size(); int i = nrows - 1, j = 0; while(i >= 0 && j < ncols){
if(array[i][j] == target) return true;
else if(array[i][j]< target ){
j++;
}else i--;
} return false;
}
};

WA警告:

之前的错误代码版本如下,由于判断条件中的 && 写成 , 造成段错误(数组越界访问):

class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
int nrows = array.size();
int ncols = array[0].size();
if( ncols == 0 || nrows == 0) return false;
for(int i = nrows - 1, j = 0; i >= 0, j < ncols; i--){
if( array[i][j] == target )
return true;
if( array[i][j] < target){
i++;
j++;
}
} return false;
}
};

T2 字符串字符不等长替换 - 从后往前

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

实现统计好空格数目从后往前写。问题是 str 所指的空间会内存泄露吧?

注意补上 '\0'(应该不会有憨憨如我补了一个'\n'...

T3 返回链表的反序 vector

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

递归或者对正序 vector reverse。

class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> rst;
if(head == NULL)return rst;
rst = printListFromTailToHead(head->next);
rst.emplace_back(head->val);
return rst;
}
}; //----------------------vv---------------------------------
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> rst; ListNode* pNode = head;
while(pNode!=NULL){
rst.emplace_back(pNode->val);
pNode=pNode->next;
} reverse(rst.begin(),rst.end());
return rst;
}
};

T4 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

递归建树。注意递归出口,当有 0 或一个节点时直接返回。

/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
if(pre.size()==0)
return NULL;
if(pre.size()==1)
return new TreeNode(pre[0]);
TreeNode* root = new TreeNode(pre[0]);
int lenl =0, lenr = 0,len = vin.size();
while(lenl<len && vin[lenl]!= pre[0])
lenl++;
vector<int> npre,nvin; npre = vector<int>(pre.begin()+1,pre.begin()+1+lenl);
nvin = vector<int>(vin.begin(),vin.begin()+lenl);
root->left = reConstructBinaryTree(npre,nvin); npre = vector<int>(pre.begin()+1+lenl,pre.end());
nvin = vector<int>(vin.begin()+lenl+1,vin.end());
root->right = reConstructBinaryTree(npre,nvin); return root;
}
};

T5 两个栈模拟队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

栈1接收入队列元素,栈2存储出队列元素,当栈2空时,把栈1元素倒到栈2中。

class Solution
{
public:
void push(int node) {
stack1.push(node);
} int pop() {
if(stack2.size()==0){
while(!stack1.empty()){
int x=stack1.top();
stack1.pop();
stack2.push(x);
}
}
int x=stack2.top();
stack2.pop();
return x;
} private:
stack<int> stack1;
stack<int> stack2;
};

T6 旋转数组中的最小元素 - 二分或暴力 ☆

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。

输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。

例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。

NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

由于旋转后,数组前半段非减,后半段非减,所以从后往前遍历,转折点一定是最小元素。如果没有转折点,那么所有元素都相等。

​ . .··

​ . ·``

但是这个转折点可以试着二分。由于转折处的右侧是最小元素,所以选择尽量让区间右端点落在最小元素上。那么:

  1. array[mid] > array[high]

    出现这种情况的array类似[3,4,5,6,0,1,2],此时最小数字一定在mid的右边。

    low = mid + 1
  2. array[mid] == array[high]:

    出现这种情况的array类似 [1,0,1,1,1] 或者[1,1,1,0,1],此时最小数字不好判断在mid左边还是右边,这时只好一步步缩小区间。

    high = high - 1
  3. array[mid] < array[high]:

    出现这种情况的array类似[2,2,3,4,5,6,6],此时最小数字一定就是array[mid]或者在mid的左边。因为右边必然都是递增的。

    high = mid

注意,考虑最后区间长为2或为3 的情况,上述的收敛方式都会使得 low 和 high 最终都指向最小元素。

class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
if(rotateArray.size()==0)
return 0;
int lo =0, hi = rotateArray.size()-1,mid; while(lo< hi){
mid = lo+((hi-lo)>>1);
if(rotateArray[mid]>rotateArray[hi])
lo=mid+1;
else if (rotateArray[mid] == rotateArray[hi])
hi-=1;
else hi=mid;
}
return rotateArray[hi];
}
};

T7 - 10 斐波那契数列 - 递推递归 - 两变量写法

T7:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 n<=39。

class Solution {
public:
int Fibonacci(int n) {
if(n==0) return 0;
if(n==1) return 1;
if(n==2) return 1;
return Fibonacci(n-1)+Fibonacci(n-2);
}
};

T8:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

// 两变量
class Solution {
public:
int jumpFloor(int number) {
if(number==0)return 1;
if(number==1)return 1;
if(number==2)return 2;
int f=1,g=2;
number-=2;
while(number--){
g=f+g;
f=g-f;
}
return g;
}
};

T9:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

// dp
class Solution {
public:
int jumpFloorII(const int number) {
int** dp=new int*[number+10];
for(int i=0;i<number+10;i++){
dp[i]=new int[number+10];
} memset(dp,0,sizeof dp); for(int i=1;i<=number;i++){
dp[1][i]=1;
}
// dp[i][j] 用i步跳上台阶j
for(int i=2;i<=number;i++){
for(int j=i;j<=number;j++){
for(int k=i-1;k<j;k++){
dp[i][j]+=dp[i-1][k];
}
}
} int ans=0;
for(int i=1;i<=number;i++){
ans+=dp[i][number];
}
return ans;// 返回的变量打错,不可原谅,,
}
};

T10:我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

类似于前面几题。

class Solution {
public:
int rectCover(int number) {
if(number==0) return 0;
if(number==1) return 1;
if(number==2) return 2;
int f=1,g=2;
number-=2;
while(number--){
g=f+g;
f=g-f;
}
return g;
}
};

T11 二进制中 1 的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

注意对于负数,右移一位会补 1 而非补零。

// 1. 去掉符号位 1
class Solution {
public:
int NumberOf1(int n) {
int cnt=0;
if(n<0) {
n &=0x7fffffff;
cnt++;
} while(n){
cnt+=(n&1);
n>>=1;
}
return cnt;
}
}; // 2. 转为 unsigned int
class Solution {
public:
int NumberOf1(int n) {
unsigned int nn=n;
int cnt=0; while(nn){
cnt+=(nn&1);
nn>>=1;
}
return cnt;
}
}; // 3. 每次 n&(n-1) 将从右边起的第一个 1 变为 0
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
}

T12 数值的整数次方 - 缜密 - 基数可能为负数

给定一个double类型的浮点数 base 和 int 类型的整数exponent。求base的exponent次方。 保证base和exponent不同时为0

class Solution {
public:
double Power(double base, int exponent) {
double ans=1;
bool neg= false; else if(exponent<0){
neg=true;
exponent=-exponent;
}
for( ; exponent; base*=base,exponent/=2){
if(exponent&1){
ans*=base;
}
}
return neg?1/ans:ans;
}
};

《剑指offer》Q01-12 (牛客10.11)的更多相关文章

  1. 《剑指offer》Q13-18 (牛客10.13)

    目录 Q13 调整数组顺序使奇数位于偶数前 Q14 链表中倒数第k个结点 Q15 反转链表 Q16 合并两个有序链表 Q17 树的子结构 Q18 二叉树的镜像 Q13 调整数组顺序使奇数位于偶数前 输 ...

  2. 剑指offer 面试12题

    面试12题: 题目:矩阵中的路径 题:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格 ...

  3. 剑指offer第12题打印从1到n位数以及大整数加法乘法

       字符和数字加减就是字符的ASCII码和数字直接加减. 方法一: 1)在字符串操作中给一个整形数字加(字符0)就是把它转化为字符,当然给一个字符减去(字符0)就可以把它转化为数字了:如果确实是最后 ...

  4. 剑指offer(12)数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 题目分析 这道题用传统的方法也可以做,只不过效率太低,这里我们用到快速幂的方法 ...

  5. 【剑指Offer】12、数值的整数次方

      题目描述:   给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   解题思路:   本题看似比较简单,是一个简单的指数运算,但需要完 ...

  6. 剑指offer【12】- 二进制中1的个数

    输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. public class Solution { public int NumberOf1(int n) { String str = ...

  7. 【剑指 Offer】12.矩阵中的路径

    题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左.右.上.下移动一格. 如果一条路径经过了矩阵的某一格,那么 ...

  8. 反转单词顺序列 牛客网 剑指Offer

    反转单词顺序列 牛客网 剑指Offer 题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但 ...

  9. 《剑指offer》面试题12:打印1到最大的n位数

    面试题12:打印1到最大的n位数 剑指offer题目12,题目如下 输入数字n,按顺序打印出1到最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的三位数999 方法一 和面试题11< ...

随机推荐

  1. 基于SSM框架的通用权限框架设计

     1. 整体解决方案概述    1.1 权限整体解决方案概述     权限设计主要有一下几大部分组成:     PassPort:    针对现在系统的分析,系统之间有部分信息是共享的,这部分信息将由 ...

  2. Python服务器开发 -- 网络基础

    Python服务器开发 -- 网络基础   网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.HTTP是高层协议,而TCP/IP是个协议集,包过许多的子协议.... 网络由下 ...

  3. <input type="file"> accept属性筛选文件类型

    如果你不希望用户上传任何类型的文件, 你可以使用 input 的 accept 属性. 设置支持 .doc / .docx / .xls / .xlsx / .pdf 格式: <input ty ...

  4. js 获取窗口大小

     //获得窗口大小         function findDimensions() //函数:获取尺寸         {             var point = {};          ...

  5. 【基本算法入门-字符串哈希(Hash)】-C++

    字符串哈希入门 说得通俗一点,字符串哈希实质上就是把每个不同的字符串转成不同的整数. 为什么会有这样的需要呢?很明显,存储一个超长的字符串和存储一个超大但是能存的下的整数,后者所占的空间会少的多,但主 ...

  6. word文档如何选择全部图片粘贴

    很多时候我们用一些管理系统的时候,发布新闻.公告等文字类信息时,希望能很快的将word里面的内容直接粘贴到富文本编辑器里面,然后发布出来.减少排版复杂的工作量. 下面是借用百度doc 来快速实现这个w ...

  7. Codevs 2492 上帝造题的七分钟 2(线段树)

    时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. " ...

  8. const char*p,char const*p,char *const p

    转自 http://blog.csdn.net/todd911/article/details/7911995 const char*, char const*, char*const的区别问题几乎是 ...

  9. Redis启动后基础只是讲解

    1.单进程 epoll是Linux内核为处理大批量文件描述符而作了改进的epoll,是Linux下多路复用IO接口select/poll的增强版本, 它能显著提高程序在大量并发连接中只有少量活跃的情况 ...

  10. JAVA的main方法

    在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的方 法有很大的不同,比如方法的名字必须是main,方法必须 ...