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

最新文章

  1. 荒废了很久的java以及微信公众平台今天拿起来看了看:这里有很好的教程
  2. 使用cocos2d-x v3.1开发小游戏(基本框架)
  3. C# 6.0部分新特性
  4. mysql 主从同步配置
  5. 采用 matlab 阅读SAR 元数据
  6. Codeforces 484B Maximum Value(高效+二分)
  7. Memcache Slab Eviction 功能测试
  8. 关于 String.intern() 的思考
  9. debian系linux墙内安装安全工具集
  10. GC调优
  11. JAVA8 in Action:行为参数化,匿名类及lambda表达式的初步认知实例整理
  12. 解决Maven项目总是回跳到jdk1.5的情况的方法
  13. Zabbix实战-简易教程--DB类--ClickHouse
  14. 20190320 Dojo常用方法总结
  15. &lt;a&gt;标签文字强制不换行
  16. Confluence 6 指派空间权限概念
  17. 解决Ubuntu14.04下sublime无法输入中文
  18. [VB.NET][C#]WAV格式文件头部解析
  19. php写杨辉三角算法
  20. Java调用C函数

热门文章

  1. WebRequest与WebResponse抽象类,DNS静态类、Ping类
  2. hbase实践之数据读取详解
  3. confluent_kafka消费时内存泄漏
  4. List 中 forEach 的用法
  5. 021_STM32程序移植之_ESP8266连接onenet
  6. 「ARC103D」Robot Arms「构造」
  7. docker容器中查看容器linux版本
  8. Zhejiang Provincial Collegiate Programming Contest + ZOJ Monthly
  9. Multiline f-strings
  10. 重读APUE(8)-进程、进程组、会话