--资料来源于网络
写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围) :
int Sum( int n )
{
return ( (long)1 + n) * n / 2; //或return (1l + n) * n / 2;
}
int Sum( int n )
{
return ( (long)1 + n) * n / 2; //或return (1l + n) * n / 2;
}
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历
序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
int inlen=in.size();
if(inlen==0)
return NULL;
vector<int> left_pre,right_pre,left_in,right_in;
//创建根节点,根节点肯定是前序遍历的第一个数
TreeNode* head=new TreeNode(pre[0]);
//找到中序遍历根节点所在位置,存放于变量gen中
int gen=0;
for(int i=0;i<inlen;i++)
{
if (in[i]==pre[0])
{
gen=i;
break;
}
}
//对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边
//利用上述这点,对二叉树节点进行归并
for(int i=0;i<gen;i++)
{
left_in.push_back(in[i]);
left_pre.push_back(pre[i+1]);//前序第一个为根节点
}
for(int i=gen+1;i<inlen;i++)
{
right_in.push_back(in[i]);
right_pre.push_back(pre[i]);
}
//和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树
//递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
head->left=reConstructBinaryTree(left_pre,left_in);
head->right=reConstructBinaryTree(right_pre,right_in);
return head;
}
};
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
class Solution
{
public:
int cou = 0;
void push(int node) {
stack1.push_back(node);
stack2.push_back(cou++);
}
int pop() {
int i = 0;
while(stack2[i] == -1)
{
i++;
}
stack2[i] = -1;
return stack1[i];
}
private:
vector<int> stack1;//存数
vector<int> stack2;//地址
};
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
int inlen=in.size();
if(inlen==0)
return NULL;
vector<int> left_pre,right_pre,left_in,right_in;
//创建根节点,根节点肯定是前序遍历的第一个数
TreeNode* head=new TreeNode(pre[0]);
//找到中序遍历根节点所在位置,存放于变量gen中
int gen=0;
for(int i=0;i<inlen;i++)
{
if (in[i]==pre[0])
{
gen=i;
break;
}
}
//对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边
//利用上述这点,对二叉树节点进行归并
for(int i=0;i<gen;i++)
{
left_in.push_back(in[i]);
left_pre.push_back(pre[i+1]);//前序第一个为根节点
}
for(int i=gen+1;i<inlen;i++)
{
right_in.push_back(in[i]);
right_pre.push_back(pre[i]);
}
//和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树
//递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
head->left=reConstructBinaryTree(left_pre,left_in);
head->right=reConstructBinaryTree(right_pre,right_in);
return head;
}
};
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
class Solution
{
public:
int cou = 0;
void push(int node) {
stack1.push_back(node);
stack2.push_back(cou++);
}
int pop() {
int i = 0;
while(stack2[i] == -1)
{
i++;
}
stack2[i] = -1;
return stack1[i];
}
private:
vector<int> stack1;//存数
vector<int> stack2;//地址
};
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
class Solution {
public:
int minNumberInRotateArray(vector<int> rotateArray) {
sort(rotateArray.begin(),rotateArray.end());
return rotateArray[0];
}
};
斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda
Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数
列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数
列以如下被以递归的方法定义:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)
这个题斐波那契数列是 0 1 1 2 3 5 8 。。。,且不是用递归的方法 返回数列中第n个的值
class Solution {
public:
int Fibonacci(int n) {
if(n<2)
return n;
int a=0,b=1,result=0;
for(int i=1;i<n;i++)
{
result=a+b;
a=b;
b=result;
}
return result;
}
};
class Solution {
public:
int Fibonacci(int n) {
if(n<2)
return n;
int a=0,b=1,result=0;
for(int i=1;i<n;i++)
{
result=a+b;
a=b;
b=result;
}
return result;
}
};
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。。对次数找规律,发现是斐波那契数列。。。
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
class Solution {
public:
int jumpFloorII(int number) {
if(number==0)
return number;
int total=1;
for(int i=1;i<number;i++)
total*=2;
return total;
}
};
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树:
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一
个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树
上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(
log(n)).
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define N 7 //插入查找树数组长度
#include <stdlib.h>
#include <stdbool.h>
#define N 7 //插入查找树数组长度
/* 二叉查找树 操作*/
typedef int Elemtype;
typedef struct BSTNode
{
Elemtype data;
struct BSTNode *lchild,*rchild;
}BSTNode,*PNode;
typedef int Elemtype;
typedef struct BSTNode
{
Elemtype data;
struct BSTNode *lchild,*rchild;
}BSTNode,*PNode;
//查找结点,树中存在结点值为data的结点返回true,否则返回false
bool SearchBST(PNode T,Elemtype data)
{
if(T == NULL)
return false;
if(data < T->data)
return SearchBST(T->lchild,data);
else if(data > T->data)
return SearchBST(T->rchild,data);
else
return true;
}
bool SearchBST(PNode T,Elemtype data)
{
if(T == NULL)
return false;
if(data < T->data)
return SearchBST(T->lchild,data);
else if(data > T->data)
return SearchBST(T->rchild,data);
else
return true;
}
//向树中插入节点,若此节点在不在树中则插入,已在树中则不插入
PNode insertBST(Elemtype data,PNode root)
{
if(root == NULL)
{
root = (PNode)malloc(sizeof(BSTNode));
root->data = data;
root->lchild = NULL;
root->rchild = NULL;
printf("%d插入树中\n",data);
return root;
}
if(data < root->data)
root->lchild = insertBST(data,root->lchild);
else if(data > root->data)
root->rchild = insertBST(data,root->rchild);
else
printf("%d已在树中,不能再次插入!!!\n",data);
return root;
}
PNode insertBST(Elemtype data,PNode root)
{
if(root == NULL)
{
root = (PNode)malloc(sizeof(BSTNode));
root->data = data;
root->lchild = NULL;
root->rchild = NULL;
printf("%d插入树中\n",data);
return root;
}
if(data < root->data)
root->lchild = insertBST(data,root->lchild);
else if(data > root->data)
root->rchild = insertBST(data,root->rchild);
else
printf("%d已在树中,不能再次插入!!!\n",data);
return root;
}
//删除一个结点:如果是叶结点则直接删除;如果结点有一个孩子,
//则直接用该结点父节点连接此结点孩子结点,删除此节点;如果结点有两个孩子结点
//则用其右子树的最小数据代替该结点的数据并递归的删除那个最小结点,因为右子树的
//最小结点不可能有左儿子因此第二次删除比较容易
PNode deleteBST(PNode root,Elemtype data)
{
if(root == NULL)
return root;
//则直接用该结点父节点连接此结点孩子结点,删除此节点;如果结点有两个孩子结点
//则用其右子树的最小数据代替该结点的数据并递归的删除那个最小结点,因为右子树的
//最小结点不可能有左儿子因此第二次删除比较容易
PNode deleteBST(PNode root,Elemtype data)
{
if(root == NULL)
return root;
if(data < root->data)
root->lchild = deleteBST(root->lchild,data);
else if(data > root->data)
root->rchild = deleteBST(root->rchild,data);
else if(root->lchild != NULL && root->rchild != NULL)
{
root->data = findMin(root->rchild)->data;
root->rchild = deleteBST(root->rchild,root->data);
}
else
root = (root->lchild != NULL) ? root->lchild : root->rchild;
return root;
}
计算一个整数n中1的个数,并把结果返回:(只要整数不为零,就一定有个1. 一个数和这个数减一相与,就是在这个数的二进制中减一
如1100&1011)
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
}
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列
坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 =
18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
bool* flag=new bool[rows*cols];
for(int i=0;i<rows*cols;i++)
flag[i]=false;
int count=moving(threshold,rows,cols,0,0,flag);//从(0,0)坐标开始访问;
delete[] flag;
return count;
}
//计算最大移动位置
int moving(int threshold,int rows,int cols,int i,int j,bool* flag)
{
int count=0;
if(check(threshold,rows,cols,i,j,flag))
{
flag[i*cols+j]=true;
//标记访问过,这个标志flag不需要回溯,因为只要被访问过即可。
//因为如果能访问,访问过会加1.不能访问,也会标记下访问过。
count=1+moving(threshold,rows,cols,i-1,j,flag)
+moving(threshold,rows,cols,i,j-1,flag)
+moving(threshold,rows,cols,i+1,j,flag)
+moving(threshold,rows,cols,i,j+1,flag);
}
return count;
}
//检查当前位置是否可以访问
bool check(int threshold,int rows,int cols,int i,int j,bool* flag)
{
if(i>=0 && i<rows && j>=0 && j<cols
&& getSum(i)+getSum(j)<=threshold
&& flag[i*cols+j]==false)
return true;
return false;
}
//计算位置的数值
int getSum(int number)
{
int sum=0;
while(number>0)
{
sum+=number%10;
number/=10;
}
return sum;
}
};
root->lchild = deleteBST(root->lchild,data);
else if(data > root->data)
root->rchild = deleteBST(root->rchild,data);
else if(root->lchild != NULL && root->rchild != NULL)
{
root->data = findMin(root->rchild)->data;
root->rchild = deleteBST(root->rchild,root->data);
}
else
root = (root->lchild != NULL) ? root->lchild : root->rchild;
return root;
}
计算一个整数n中1的个数,并把结果返回:(只要整数不为零,就一定有个1. 一个数和这个数减一相与,就是在这个数的二进制中减一
如1100&1011)
public class Solution {
public int NumberOf1(int n) {
int count = 0;
while(n!= 0){
count++;
n = n & (n - 1);
}
return count;
}
}
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列
坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 =
18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
class Solution {
public:
int movingCount(int threshold, int rows, int cols)
{
bool* flag=new bool[rows*cols];
for(int i=0;i<rows*cols;i++)
flag[i]=false;
int count=moving(threshold,rows,cols,0,0,flag);//从(0,0)坐标开始访问;
delete[] flag;
return count;
}
//计算最大移动位置
int moving(int threshold,int rows,int cols,int i,int j,bool* flag)
{
int count=0;
if(check(threshold,rows,cols,i,j,flag))
{
flag[i*cols+j]=true;
//标记访问过,这个标志flag不需要回溯,因为只要被访问过即可。
//因为如果能访问,访问过会加1.不能访问,也会标记下访问过。
count=1+moving(threshold,rows,cols,i-1,j,flag)
+moving(threshold,rows,cols,i,j-1,flag)
+moving(threshold,rows,cols,i+1,j,flag)
+moving(threshold,rows,cols,i,j+1,flag);
}
return count;
}
//检查当前位置是否可以访问
bool check(int threshold,int rows,int cols,int i,int j,bool* flag)
{
if(i>=0 && i<rows && j>=0 && j<cols
&& getSum(i)+getSum(j)<=threshold
&& flag[i*cols+j]==false)
return true;
return false;
}
//计算位置的数值
int getSum(int number)
{
int sum=0;
while(number>0)
{
sum+=number%10;
number/=10;
}
return sum;
}
};