题目描述
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
每行二分
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
for( int i = 0 ; i < array.size() ; i++ ){
int len = array[i].size();
int pos = lower_bound(array[i].begin(),array[i].end(),target)-array[i].begin();
if( pos < len && target == array[i][pos] ) return true ;
}
return false;
}
};
题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
从后往前遍历,移动
class Solution {
public:
void replaceSpace(char *str,int length) {
int c = 0 ;
for( int i = 0 ; i < length ; i++ ){
if( str[i] == ' ' ){
c ++ ;
}
}
for( int i = length - 1; i >= 0 ; i-- ){
if( str[i] != ' ' ) str[i+2*c] = str[i] ;
else{
c-- ;
str[i+2*c] = '%';
str[i+2*c+1] = '2';
str[i+2*c+2] = '0';
}
}
}
};
题目描述
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
用栈
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int>a;
stack<int>s ;
while( head ){
s.push(head->val) ;
head = head -> next ;
}
int x ;
while( s.size() ){
x = s.top() ;
s.pop() ;
a.push_back(x) ;
}
return a ;
}
};
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
递归建立二叉树:
每次以前序序列第一个x为根,在中序中找到x,左边的为左子树中序序列,右边的为右子树的中序序列;
再将得到的左,右子树的前序,中序序列分别重复上述过程;
class Solution {
public:
TreeNode* reConstructBinaryTree( vector<int> pre,vector<int> vin ) {
if ( !pre.size() || !vin.size() ) {
return NULL;
}
TreeNode* rt = new TreeNode(pre[0]);
for (int i = 0; i < vin.size(); i++) {
if ( vin[i] == pre[0]) {
//[L,R)
vector<int> p1( pre.begin()+1 , pre.begin()+i+1 ) ;
vector<int> v1( vin.begin() , vin.begin() + i ) ;
rt->left = reConstructBinaryTree( p1 , v1 );
vector<int> p2( pre.begin()+i+1 , pre.end() ) ;
vector<int> v2( vin.begin()+i+1 , vin.end() ) ;
rt->right = reConstructBinaryTree( p2 , v2 );
break;
}
}
return rt;
}
};
题目描述
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
Push则直接放入stack1
Pop则将stack1中全放入2,再取stack2栈顶
class Solution
{
public:
void push(int node) {
stack1.push(node) ;
}
int pop() {
if( !stack2.size() ){
while( stack1.size() ){
stack2.push(stack1.top()) ;
stack1.pop() ;
}
}
int tmp = stack2.top() ; stack2.pop() ;
return tmp ;
}
private:
stack<int> stack1;
stack<int> stack2;
};
题目描述
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
class Solution {
public:
int minNumberInRotateArray(vector<int> a) {
if( !a.size() ) return 0 ;
sort( a.begin() , a.end() );
return a[0] ;
}
};
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
class Solution {
public:
int Fibonacci(int n) {
int a[50] ;
a[0] = 0 ;
a[1] = 1 ;
for( int i = 2 ; i <= 40 ; i++ ){
a[i] = a[i-1] + a[i-2] ;
}
return a[n] ;
}
};
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
递推:f[n] = f[n-1] + f[n-2]
class Solution {
public:
int jumpFloor(int number) {
int n1 = 2 ;
int n2 = 1 ;
int ans = 0 ;
if( number == 1 ) return 1 ;
else if( number == 2 ) return 2 ;
for( int i = 3 ; i <= number ; i++ ){
ans = n2 + n1 ;
n2 = n1 ;
n1 = ans ;
}
return ans ;
}
};
题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
方法一:
f[n] = f[n-1] + f[n-2] + … + f[1]
方法二:
f[n] = f[n-1] + f[n-2] + … + f[1]
f[n-1] = f[n-2] + f[n-3] + … + f[1]
相减:f[n] = 2*f[n-1]
故结果为2^(n-1)
class Solution {
public:
int jumpFloorII(int number) {
int ans = 2 ;
if( number == 1 ) return 1 ;
else if( number == 2 ) return 2 ;
int res = 3 ;
for( int i = 3 ; i <= number ; i++ ){
ans = res + 1 ;
if( i != number ) res += ans;
}
return res + 1 ;
}
};
class Solution {
public:
int jumpFloorII(int number) {
return 1<<(number-1);
}
};
题目描述
我们可以用2 * 1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
n = 1 , 一种
n = 2 ,横,竖两种
n = 3,第3列竖着放,用1列,剩 n = 2,2种
第3列横着放,用了2列,剩 n = 1,1种。共3种
… n=k时,只需要管横竖怎么放,故f[k] = f[k-1] + f[k-2]
class Solution {
public:
int rectCover(int n) {
if( !n ) return 0;
if( n == 1 ) return 1;
if( n == 2 ) return 2;
return rectCover( n - 1 ) + rectCover( n - 2 ) ;
}
};
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
方法一:补码和移码关系
方法二:n&(n-1)->将最右边的1变为0
方法三:当做无符号数逻辑右移(补0)(有符号数负数补码右移补1)
int NumberOf1(int n) {
if( !n ) return 0 ;
long long ans = (long long)n ;
int c = 0 ;
if( n < 0 ) ans += (1ll<<32) ; //补码,移码
while( ans ){
if( ans & 1 ) c++ ;
ans >>= 1 ;
}
return c ;
}
class Solution {
public:
int NumberOf1(int n) {
int c = 0 ;
while( n ){
c ++ ;
n &= (n-1); //每次使最右1变为0
}
return c ;
}
};
int NumberOf1(int n) {
int c = 0 ;
unsigned int ans = (unsigned int)n ; // Logical Shift Right (add 0)
while( ans ){
if( ans & 1 ) c ++ ;
ans >>= 1 ;
}
return c ;
}
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0
class Solution {
public:
double Power(double a, int b) {
if( !a ) return 0 ;
if( !b ) return 1 ;
double res = 1.0 ;
int c = abs(b) ;
for( int i = 0 ; i < c ; i++ ){
res = 1.0 * res * a ;
}
if( b < 0 ) res = (double)1.0/res ;
return res ;
}
};
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
类似插入排序
class Solution {
public:
void reOrderArray(vector<int> &a) {
int len = a.size() ;
for( int i = 0 ; i < len ; i ++ ){
if( !(a[i]&1) ) continue ;
for( int j = i - 1 ; j >= 0 ; j-- ){
if( !(a[j]&1) && (a[j+1]&1) ){
swap(a[j+1],a[j]) ;
}
}
}
}
};
题目描述
输入一个链表,输出该链表中倒数第k个结点。
队列只存储k个值
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* Head, unsigned int k) {
if( Head == NULL ) return Head ;
unsigned int c = 0 ;
queue<ListNode*>q ;
while( Head ){
q.push(Head);
if( c < k ) c ++ ;
else q.pop() ;
Head = Head -> next ;
}
return ( c < k ? NULL : q.front() ) ;
}
};
题目描述
输入一个链表,反转链表后,输出新链表的表头。
p 指向x左节点,(初始null)q指向x节点(初始头指针),cur指向x下一节点
遍历一遍,将链表反转
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* head) {
if( head == NULL ) return head ;
ListNode* p = NULL;
ListNode* cur = head -> next ;
ListNode* q = head;
while( cur ){
q -> next = p ;
p = q ;
q = cur ;
cur = cur -> next ;
}
q -> next = p ;
return q ;
}
};
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
归并
设置L指针为新的表头(初始指向H1,H2更小的那个)
遍历H2与H1,比较大小,H2小则插入H1前面;
H2大则移动H1
最后H2不空则链接到后面
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* H1, ListNode* H2){
if( H1 == NULL && H2 == NULL ) return NULL ;
if( H1 == NULL ) return H2 ;
if( H2 == NULL ) return H1 ;
ListNode* pre = new ListNode(-1) ; //pre初始化
ListNode* tmp ;
ListNode* L ;
if( H1 -> val < H2 -> val ){
L = H1 ;
}else L = H2 ;
while( H1 && H2 ){
if( H2 -> val <= H1 -> val ){
tmp = H2 -> next ;
pre -> next = H2 ;
H2 -> next = H1 ;
pre = H2 ;
H2 = tmp ;
}else{
pre = H1 ;
H1 = H1 -> next ;
}
}
if( H2 ){
pre -> next = H2 ;
}
return L ;
}
};
来源:CSDN
作者:Dave_L
链接:https://blog.csdn.net/FrankAx/article/details/103743624