/*3.求子数组的最大和
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。*/
#include <iostream.h>
int maxSum(int* a, int n)
{
int sum=0;
int b=0;
for(int i=0; i<n; i++)
{
if(b<0)
b=a[i];
else
b+=a[i];
if(sum<b)
sum=b;
}
return sum;
}
int main()
{
int a[10]={1,-8,6,3,-1,5,7,-2,0,1};
cout<<maxSum(a,10)<<endl;
return 0;
}
/*
4.在二元树中找出和为某一值的所有路径
题目:输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。
例如 输入整数22和如下二元树
10
/ /
5 12
/ /
4 7
则打印出两条路径:10, 12和10, 5, 7。
二元树节点的数据结构定义为:
struct BinaryTreeNode // a node in the binary tree
{
int m_nValue; // value of node
BinaryTreeNode *m_pLeft; // left child of node
BinaryTreeNode *m_pRight; // right child of node
};
*/
//二元树节点
class BinaryTreeNode
{
int m_nValue; // value of node
BinaryTreeNode m_pLeft; // left child of node
BinaryTreeNode m_pRight; // right child of node
public BinaryTreeNode(int m_nValue)
{
this.m_nValue = m_nValue;
}
public boolean left()
{
return m_pLeft == null ? false : true;
}
public boolean right()
{
return m_pRight == null ? false : true;
}
public boolean isLeaf()
{
return !(left() || right());
}
public BinaryTreeNode getChild(int lr)
{
return lr == 0 ? m_pLeft : m_pRight;
}
}
//记录结果路径的链表节点
class Result
{
String path;
Result next;
Result pre;
public Result(String path)
{
this.path = path;
}
}
public class MicroSoftEx004
{
/**二元树根节点*/
private BinaryTreeNode root;
/**目标数*/
int target;
/**累计变量*/
private int count;
/**记录路径*/
private String path = "";
/**记录结果路径的链表*/
private Result result = new Result(null);
/**构建二元树*/
public void bulitTree()
{
root = new BinaryTreeNode(10);
root.m_pLeft = new BinaryTreeNode(5);
root.m_pRight = new BinaryTreeNode(12);
root.m_pLeft.m_pLeft = new BinaryTreeNode(4);
root.m_pLeft.m_pRight = new BinaryTreeNode(7);
}
/*
* 在二元树中找出和为某一值的所有路径
* 先搜索左子树,后搜索右子树,
当遇到非叶子节点累计大于等于目标值时或叶子节点累计不等于目标值时该路径搜索失败
* 二元树节点,左子树为0,右子树为1
*/
public void solve(BinaryTreeNode root, int lr)
{
int len = path.length() + 1;//记录当前是第几层节点
count += root.m_nValue;//累加
int temp = count;//记录当前值
if(count < target && !root.isLeaf())
{
//非叶子节点且累计小于目标值时继续搜索
path += lr + "";//记录当前搜索的子树的左右[0|1]
if(root.left())
solve(root.m_pLeft, 0);//搜索左子树
path = path.substring(0, len);//去除左子树的路径信息
count = temp;//还原当前值
if(root.right())
solve(root.m_pRight, 1);//搜索右子树
count = temp;//还原当前值
}
else if(count == target && root.isLeaf())
{
//找到所需路径
path += lr + "";//记录当前搜索的子树的左右[0|1]
result.next = new Result(path);//添加新的结果
result.next.pre = result;//新结果前驱为之前结果节点
result = result.next;//指向新结果节点
}
}
public static void main(String[] args)
{ // TODO Auto-generated method stub
MicroSoftEx004 ex = new MicroSoftEx004();
ex.bulitTree();
ex.target = 22;
ex.solve(ex.root, 0);
BinaryTreeNode root;
while(ex.result.path != null)
{
root = ex.root;
System.out.print(root.m_nValue + " ");
for(int i = 1;i < ex.result.path.length();i++)
{
root = root.getChild(Integer.parseInt(ex.result.path.substring(i, i + 1)));
System.out.print(root.m_nValue + " ");
}
System.out.println();
ex.result = ex.result.pre;
}
}
}
/*5.查找最小的k个元素
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,
则最小的4个数字为1,2,3和4。
*/
//use stl set to make heap
#include <set>
#include <vector>
#include <iostream>
using namespace std;
typedef multiset<int, greater<int>> IntHeap;
void FindKLeastNumbers(const vector<int> &data, IntHeap& leastNumbers, unsigned int k)
{
leastNumbers.clear();
if(k==0 || data.size()<k)
return;
vector<int>::const_iterator iter= data.begin();
for(;iter!=data.end();++iter)
{
if(leastNumbers.size()<k)
leastNumbers.insert(*iter);
else {
IntHeap::iterator iterFirst = leastNumbers.begin();
if(*iter< *(leastNumbers.begin()))
{
leastNumbers.erase(iterFirst);
leastNumbers.insert(*iter);
}
}
}
}