一、满二叉搜索树
/** * 给定一个二叉树的层序遍历判断是不是一颗满二叉搜索树 */
大致分为这么几步:
1.处理输入
2.根据满二叉树的节点数量进行排除
3.构建树
4.递归判断
public static Node root;
public static void isManTree(){
Scanner sc = new Scanner(System.in);
ArrayList<Integer> integers=new ArrayList<>();
while (sc.hasNextInt()) {
integers.add(sc.nextInt());
}
if (integers.size()<2){
System.out.println("True");
return;
}else if (integers.size()%2==0){
System.out.println("False");
return;
}
int size=integers.size()+1;
while (size!=1){
if (size%2!=0){
System.out.println("False");
return;
}
size/=2;
}
root=new Node(integers.get(0));
creatTree(root,integers);
if (isMantree(root)){
System.out.println("True");
}else {
System.out.println("False");
}
}
private static void creatTree(Node root, ArrayList<Integer> integers) {
LinkedBlockingQueue<Node> nodes=new LinkedBlockingQueue<Node>();
nodes.add(root);
int num=1,index=0,length=integers.size();
while (index+1<length){
for (int i=0;i<num;i++){
Node node=nodes.poll();
System.out.println(num+" "+index);
Node left=new Node(integers.get(++index));
Node right=new Node(integers.get(++index));
node.left=left;
node.right=right;
nodes.offer(left);
nodes.offer(right);
}
num*=2;
}
}
public static boolean isMantree(Node root){
if (root.left==null||root.right==null)return true;
if (root.left.value>root.value||root.right.value<root.value){
return false;
}
return isMantree(root.left)&&isMantree(root.right);
}
static class Node{
int value;
Node left;
Node right;
Node(int value){
this.value=value;
}
}
其实可以再优化一下,在构建树的时候就判断是否满足二叉搜索树的条件
二、次品率
题目:
/** * 穷否病食品加工厂今年产品质量出现了大问题!它所包装生产的苹果一箱按标准应该是6±0.1公斤(6000±100克), * 但是因为生产流水线出现了一些无法排查的问题,有些产品会缺斤少两,如果一箱苹果少于5900克,则视为次品。 * 现在给你一批产品每箱的重量,你需要计算这批产品的次品率是多少。 * * 输入 * 第一行一个数n,表示苹果的箱数。 * 接下来一行n个整数(以克为单位),第i个数表示第i箱的重量。 * 输出 * 输出一个百分数(保留两位小数,四舍五入)。具体参见样例。 * * 样例输入 * 5 * 5900 6100 6000 6101 5899 * 样例输出 * 20.00% * * 提示 * 输入样例2 * 6 * 5900 6100 6000 6101 5899 6010 * * 输出样例2 * 16.67% */
此题为百度2020届Android实习生的笔试题,题很简单,主要的问题在四舍五入和保留两位小数上
注意这样的一种情况,当次品率为25%时,要输出25.00%而不是25.0%
public static void errorRate() {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
int[] nums = new int[num];
for (int i = 0; i < num; i++) {
nums[i] = scanner.nextInt();
}
float error = 0;
for (int apple : nums) {
if (apple < 5900) {
error++;
}
}
float errorRate = (error * 100) / num;
double realErrorRate = Math.round(errorRate * 100) / 100.0;
String string = String.valueOf(realErrorRate);
int index = string.indexOf(".");
if (string.length() - index < 3) {
System.out.println(realErrorRate + "0%");
} else {
System.out.println(realErrorRate + "%");
}
scanner.close();
}
三、最大战力
题目:
/** * 有一个军团要打仗,有n名士兵(一定是3的倍数),每一个士兵都有自己的物理攻击力和魔法攻击力, * 要分成三个等大的小队派去三块空间打仗,物理空间只能发挥物理攻击力,魔法空间只能发挥魔法攻击力, * 虚无空间只能发挥物理攻击力,魔法攻击力之和的一半,你要进行合理的分配使三个小队的总战力最大, * 问最大是多少? */
这道题也是百度2020届Android实习生的笔试题
要使总的战力之和最大,那么问题的核心就在如何使战力损失最小上,也就是说一个士兵去所在的战场上的价值最高
比如说有两个士兵分别为 甲(5,2)和乙(6,9),那么甲士兵明显适合去物理战场,及时乙士兵的物理战力更高,但是应该让每个士兵发挥每个士兵的长处,而不是单纯看一方面
那么思路就清楚了,这道题有两种解法,最暴力的就是全排列,让前n/3的人去物理空间,中间n/3的人去魔法空间,后n/3的人去虚无空间,其实顺序无所谓,主要是覆盖所有分配情况,但是这样写比较麻烦而且效率特别低下
还有一种解法就是让各自发挥自己的最大价值,用一个数组存储各自的物理战力减去魔法战力,然后进行从小到大排序,这样前面的人就是物理攻击力远高于魔法攻击力的,让他们去物理空间最合适了,这样就把去物理空间的n/3的人订好了,最后的人肯定是魔法高于物理的,适合去魔法空间,那去魔法空间的人也订好了,剩下中间n/3的人去虚无,这里要注意一下,因为物理战力加魔法战力之和除以2可能有小数,这也要考虑到,不能白白损失,所以这里要用float计算。
其中还有一个问题就是对物理魔法差值排序时,要同时保存对应的下标,别把士兵对应的值弄错了
public static void maxPower(int n,int[] wuli,int[] mofa){
int[] chazhi=new int[n];
int[] index=new int[n];
for (int i=0;i<n;i++){
chazhi[i]=wuli[i]-mofa[i];
index[i]=i;
}
int temp;
for (int i = 0; i < n; i++) {//冒泡趟数
for (int j = 0; j < n - i - 1; j++) {
if (chazhi[j] < chazhi[j+1]) {
temp = chazhi[j];
chazhi[j] = chazhi[j + 1];
chazhi[j + 1] = temp;
temp=index[j];
index[j]=index[j+1];
index[j+1]=temp;
}
}
}
for (int a:chazhi){
System.out.print(a+" ");
}
System.out.println();
for (int a:index){
System.out.print(a+" ");
}
System.out.println();
float maxPower=0;
int xuwuPower=0;
for (int i=0;i<n;i++){
if (i<n/3){
maxPower+=wuli[index[i]];
}else if (i<n*2/3){
xuwuPower+=wuli[index[i]]+mofa[index[i]];
}else {
maxPower+=mofa[index[i]];
}
}
maxPower+=xuwuPower/2.0;
System.out.println(maxPower);
}
四、小Q喝果汁
题目:
/** *小Q的父母要出差,留给小Q n 瓶饮料,他们的容量为v[i]毫升,小Q想先喝s毫升, * 但是他想让剩下的饮料中最少的尽可能的多,问最少的饮料是多少毫升 * 不足返回-1 * 例: * 输入: * 3 5 * 1 1 1 * 输出: * -1 * 输入: * 2 9 * 5 10 * 输出: * 3 */
这道题是腾讯2020届Android实习生笔试题
这道题需要注意的一点便是瓶子的容量,你可以随便的倒饮料,但是不能把超过瓶子容量的果汁倒进瓶子中
要想求最少的饮料是多少,那这个值一定小于等于最小的瓶子容量
总体思路:求出最小容量,喝掉比最小容量多的果汁,没喝够就不断每瓶喝1毫升,喝够了返回最小值
首先一个for循环求出最小容量和总饮料数量
如果总饮料数量小于s,说明不够喝 打印-1
如果总饮料数量减去s小于瓶数,那么肯定有空瓶 打印0
喝掉比最小容量多的饮料,如果没喝够就每瓶喝一毫升,最小容量减1
打印最小容量
private static void drinkJuice(int n,int[] v,int s){
int current=0;
int min=Integer.MAX_VALUE;
int count=0;
for (int i=0;i<n;i++){
if (min>v[i]){
min=v[i];
}
count+=v[i];
}
if (count<s){
System.out.println(-1);
return;
}else if (count-s<n){
System.out.println(0);
return;
}
for (int i=0;i<n;i++){
current+=v[i]-min;
}
while (current<s){
min--;
current+=n;
}
System.out.println(min);
}