出题:把二元查找树转变成排序的双向链表。输入一棵二元查找树,要求将该二元查找树按照中序转换成一个排序的双向链表,要求不能创建任何新的节点,只能调整指针的指向;

分析:

  • 递归的思路,当前节点需要进行的处理,并使用递归调用和返回值将子问题链接起来;
  • 首先明白二元查找树的特性,变成有序双向链表后当前根节点的左节点为其原来左子树的最右节点,右节点为其原来右子树的最左节点;因此策略就是针对当前根节点索引的子树,首先判断其为上层节点的右子树还是左子树,从而决定返回最右还是最右节点;然后再递归处理当前根节点的左右子树;

解题:

 #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为双向链表 & 查找栈中的最小元素的更多相关文章

  1. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  2. 笔试算法题(24):找出出现次数超过一半的元素 & 二叉树最近公共父节点

    出题:数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字: 分析: 解法1:首先对数组进行排序,时间复杂度为O(NlogN),由于有一个数字出现次数超过了数组的一半,所以如果二分数组的话, ...

  3. 笔试算法题(34):从数字序列中寻找仅出现一次的数字 & 最大公约数(GCD)问题

    出题:给定一个数字序列,其中每个数字最多出现两次,只有一个数字仅出现了一次,如何快速找出其中仅出现了一次的数字: 分析: 由于知道一个数字异或操作它本身(X^X=0)都为0,而任何数字异或操作0都为它 ...

  4. 笔试算法题(15):-1到N中包含1的数字的个数 & 连续和为N的序列

    出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数: 分析: 从左向右处理string表示的数字:当前数字长度为n,判断最左边一位数字字符: 如果是0,则直接递归下一位: 如果是 ...

  5. 笔试算法题(14):整数二进制表示中的1 & 判定栈的push和pop序列是否对应

    出题:输入一个整数,要求计算此整数的二进制表示中1的个数 分析: 如果整数表示为k,当其是负数的时候,使用1<<i分别检测k的每一位:当其位整数的时候,则k/2表示将其二进制表示右移一位, ...

  6. 笔试算法题(22):二分法求旋转数组最小值 & 骰子值概率

    出题:将一个数组最开始的k个(K小于数组大小N)元素照搬到数组末尾,我们称之为数组的旋转:现在有一个已经排序的数组的一个旋转,要求输出旋转数组中的最小元素,且时间复杂度小于O(N): 分析: 时间复杂 ...

  7. 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素

    [python]Leetcode每日一题-寻找旋转排序数组中的最小元素 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...

  8. 【python】Leetcode每日一题-寻找旋转排序数组中的最小元素2

    [python]Leetcode每日一题-寻找旋转排序数组中的最小元素2 [题目描述] 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组nums ...

  9. 笔试算法题(31):将有序数组转换成BST表示 & 线段树的应用

    出题:要求将一个有序整数数组转换成最小深度的Binary Search Tree表示: 分析:由于需要是最小深度,所以BST应保持平衡,左右节点数大致相当,并且BST中当前根节点大于所有其左子树中的元 ...

随机推荐

  1. 开源ORM

    Farseer.net轻量级开源框架 目录 https://github.com/steden/Farseer.net ---------------------------------- SunSo ...

  2. bzoj 2337 [HNOI2011]XOR和路径【高斯消元+dp】

    首先,我们发现,因为是无向图,所以相连的点之间是有"依赖性"的,所以不能直接用dp求解. 因为是xor,所以按位处理,于是列线性方程组,设$ x[i] $为点i到n异或和为1的期望 ...

  3. bzoj 3677: [Apio2014]连珠线【树形dp】

    参考:http://www.cnblogs.com/mmlz/p/4456547.html 枚举根,然后做树形dp,设f[i][1]为i是蓝线中点(蓝线一定是父子孙三代),f[i][0]为不是,转移很 ...

  4. nmcli 学习小结

    nmcli 是Redhat提供的网络配置编辑工具, 它可直接编辑/etc/sysconfig/network-scripts/ifcfg-xxx , 它是NetworkManager服务的客户端工具, ...

  5. zoj 3649 lca与倍增dp

    参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的 ...

  6. Android 线程池系列教程(3) 创建线程池

    Creating a Manager for Multiple Threads 上一课  下一课 1.This lesson teaches you to Define the Thread Pool ...

  7. 228 Summary Ranges 汇总区间

    给定一个无重复元素的有序整数数组,返回数组中区间范围的汇总. 示例 1: 输入: [0,1,2,4,5,7]输出: ["0->2","4->5",& ...

  8. ASP.NET MVC+Bootstrap个人博客之修复UEditor编辑时Bug(四)

    我的个人博客站在使用百度富文本编辑器UEditor修改文章时,遇到了一些问题,(不知是bug,还是我没有配置好).但总算找到了解决方法,在此记录下来. 遇到的问题: 正常来讲,进入文章修改页,只需将U ...

  9. DEV—【GridControl 按钮列无法触发点击事件解决方案】

    需要在按钮列的OptionColumn属性栏中找到下面两个属性,并且改为True AllowEdit=True,AllowFocus=True.

  10. 为OS X开发者准备的15个超棒应用

    几乎所有的开发人员在他们日常的开发工作中都有他们自己不可缺少的工具或实用程序集. 这些工具中的每一个都提供了特定的功能,大多数开发者都已经将他们集成到了其工作流程中. 使用这些工具或实用程序不单单只是 ...