笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素
出题:把二元查找树转变成排序的双向链表。输入一棵二元查找树,要求将该二元查找树按照中序转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整指针的指向;
分析:
- 递归的思路,当前节点需要进行的处理,并使用递归调用和返回值将子问题链接起来;
- 首先明白二元查找树的特性,变成有序双向链表后当前根节点的左节点为其原来左子树的最右节点,右节点为其原来右子树的最左节点;因此策略就是针对当前根节点索引的子树,首先判断其为上层节点的右子树还是左子树,从而决定返回最右还是最右节点;然后再递归处理当前根节点的左右子树;
解题:
#include <stdio.h>
#include <malloc.h>
#include <string.h> typedef struct Node {
int value;
Node *left;
Node *right;
} *NodePtr; Node* MostLeft(Node *current) {
Node* temp=current;
while(temp->left!=NULL) {
temp=temp->left;
}
return temp;
} Node* MostRight(Node *current) {
Node* temp=current;
while(temp->right!=NULL) {
temp=temp->right;
}
return temp;
} Node* Transfer(Node *current, bool isRight) { if(current==NULL) return NULL;
/**
* 在树结构被破坏之前预先查找好需要返回的节点
* */
Node* turnback = (isRight ? MostLeft(current) : MostRight(current));
/**
* 递归处理左右子树,将具体返回的节点推迟到子树解决
* */
if(current->left!=NULL) {
current->left=Transfer(current->left,false);
current->left->right=current;
}
if(current->right!=NULL) {
current->right=Transfer(current->right,true);
current->right->left=current;
}
/**
* 根据isRight的值,和current是否有左右子树返回不同的节点
* */
return turnback;
}
出题:定义stack数据结构,除Push和Pop函数外要求增加Min函数,其功能是找到stack中最小的元素,要求所有函数时间复杂度都是O(1);
分析:
- 使用辅助stack结构依次将目前的最小元素压入栈,设置CurMin元素记录当前stack中的最小元素,每次Push的新元素都与CurMin比较,若新元素更小则将其压入辅助栈;每次Pop元素都与CurMin比较,若就是CurMin元素则将辅助栈栈顶元素出栈;
解题:
class MyStack {
private:
int *array;
int capability;
int length;
int head;
int tail;
public:
MyStack(int n=): array((int*)malloc(sizeof(int)*n)), head(),tail(),capability(n), length() {}
~MyStack() {delete [] array;}
bool isFull() {
if(length == capability) return true;
return false;
}
bool isEmpty() {
if(length == ) return true;
return false;
}
/**
* head当前的指向位置是下一次将push的元素的
* */
bool push(int n) {
if(isFull()) return false;
array[head]=n;
head=(head+)%(capability+);
length++;
return true;
}
/**
* tail当前指向的位置是下一次将pop的元素的
* */
bool pop(int *n) {
if(isEmpty()) return false;
*n=array[tail];
tail=(tail+)%(capability+);
length--;
return true;
}
void showStack() {
int i=tail;
int temp=length;
printf("\nnew path\n");
while(temp>) {
printf("%d, ",array[i++]);
temp--;
}
}
};
class MinStack {
private:
MyStack *mainStack;
MyStack *assiStack;
int curMin;
public:
MinStack(): mainStack(new MyStack()),assiStack(new MyStack()),curMin() {}
/**
* 仅当出现新的最小元素时,才将前一个最小元素压入assiStack
* */
bool push(int n) {
if(mainStack->push(n)) {
if(n<curMin) {
assiStack->push(curMin);
curMin=n;
}
return true;
}
return false;
}
/**
* 仅当mianStack的pop元素等于curMin时,才从assiStack中新pop出一个元素
* */
bool pop(int *n) {
if(mainStack->pop(n)) {
if(*n == curMin) {
int *temp;
assiStack->pop(temp);
curMin=*temp;
}
return true;
}
return false;
}
int min() {
return curMin;
}
};
笔试算法题(05):转换BST为双向链表 & 查找栈中的最小元素的更多相关文章
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- 笔试算法题(24):找出出现次数超过一半的元素 & 二叉树最近公共父节点
出题:数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字: 分析: 解法1:首先对数组进行排序,时间复杂度为O(NlogN),由于有一个数字出现次数超过了数组的一半,所以如果二分数组的话, ...
- 笔试算法题(34):从数字序列中寻找仅出现一次的数字 & 最大公约数(GCD)问题
出题:给定一个数字序列,其中每个数字最多出现两次,只有一个数字仅出现了一次,如何快速找出其中仅出现了一次的数字: 分析: 由于知道一个数字异或操作它本身(X^X=0)都为0,而任何数字异或操作0都为它 ...
- 笔试算法题(15):-1到N中包含1的数字的个数 & 连续和为N的序列
出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数: 分析: 从左向右处理string表示的数字:当前数字长度为n,判断最左边一位数字字符: 如果是0,则直接递归下一位: 如果是 ...
- 笔试算法题(14):整数二进制表示中的1 & 判定栈的push和pop序列是否对应
出题:输入一个整数,要求计算此整数的二进制表示中1的个数 分析: 如果整数表示为k,当其是负数的时候,使用1<<i分别检测k的每一位:当其位整数的时候,则k/2表示将其二进制表示右移一位, ...
- 笔试算法题(22):二分法求旋转数组最小值 & 骰子值概率
出题:将一个数组最开始的k个(K小于数组大小N)元素照搬到数组末尾,我们称之为数组的旋转:现在有一个已经排序的数组的一个旋转,要求输出旋转数组中的最小元素,且时间复杂度小于O(N): 分析: 时间复杂 ...
- 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素
[python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...
- 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素2
[python]Leetcode每日一题-寻找旋转排序数组中的最小元素2 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...
- 笔试算法题(31):将有序数组转换成BST表示 & 线段树的应用
出题:要求将一个有序整数数组转换成最小深度的Binary Search Tree表示: 分析:由于需要是最小深度,所以BST应保持平衡,左右节点数大致相当,并且BST中当前根节点大于所有其左子树中的元 ...
随机推荐
- 真正认识 realloc 的工作方式(转载)
转自:http://www.cnblogs.com/ren54/archive/2008/11/20/1337545.html realloc 用过很多次了.无非就是将已经存在的一块内存扩大. cha ...
- bzoj 2157: 旅游【树链剖分+线段树】
裸的树链剖分+线段树 但是要注意一个地方--我WA了好几次才发现取完相反数之后max值和min值是要交换的-- #include<iostream> #include<cstdio& ...
- Educational Codeforces Round 52 (Rated for Div. 2) F. Up and Down the Tree 树型DP
题面 题意:给你一棵树,你起点在1,1也是根节点,你每次可以选择去你子树的某个叶子节点,也可以选择,从叶子节点返回距离不超过k的一个根, 也就是说,你从1开始,向下跳,选择一个叶子(就是没有子树的节点 ...
- unsign 字段相减出现负数解决方法
在项目中做数据统计的时候需要用到几个字段相减得到想要的值,但是因为字段都是无符号,相减出现mysql 错误 BINGINT UNSIGNED VALUE .. 在c语言中两个无符号相减值为负数,该值 ...
- iOS端样式错位
在iOS端上点击的时候触发点会在当前元素上方,原因是在最外层使用了fixed定位,换成绝对或相对定位解决问题
- mysql 状态查询
select COUNT(case when info.State = '0' then State end ) as daichuliCount, COUNT(case when info.St ...
- ————————C语言中快速排序方法——————————————
在对浮点型排序是一定要用三木运算符(三目运算符内容下去自己看),因为如果也是用整形那样的减法的时候如果是两个十分相近的数字 可能返回一个小数(自己一会去试试),冉冉他cmp返回值是int(试试别的)因 ...
- Qt事件系统之二:鼠标事件和滚轮事件
在Qt中,事件作为一个对象,继承自 QEvent 类,常见的有键盘事件 QKeyEvent.鼠标事件 QMouseEvent 和定时器事件 QTimerEvent 等,与 QEvent 类的继承关系图 ...
- [Usaco2017 Open]Modern Art 2
Description Having become bored with standard 2-dimensional artwork (and also frustrated at others c ...
- 【洛谷2304_LOJ2134】[NOI2015]小园丁与老司机(动态规划_网络流)
题目: 洛谷 2304 LOJ 2134 (LOJ 上每个测试点有部分分) 写了快一天 -- 好菜啊 分析: 毒瘤二合一题 -- 注意本题(及本文)使用 \(x\) 向右,\(y\) 向上的「数学坐标 ...