1)讲一颗有100个节点的完全二叉树从根节点开始,每一层从左向右依次进行编号,根节点编号是1,那么编号98的节点的父亲节点编号为_49_;
之前咱们按照(i-1)/2;算的是根节点从0开始,以1进行编号,那么这个1就不可以减了
2)用不带头结点的单链表存储队列,他的队头指针指向队头节点,他的队尾指针指向队尾节点,那么进行出队操作的时候:
队头,队尾指针可能都要进行修改,因为只有一个节点的时候,头指针指向这个节点,尾指针也是指向这个节点,当进行出队列的时候,head=null,tail=null
iboFnacci数列是这样定义的:
F[0] = 0 F[1] = 1 for each i ≥ 2: F[i] = F[i-1] + F[i-2]
因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, …,在Fibonacci数列中的数我们称为Fibonacci数,给你一个N,你想让其变为一个Fibonacci数,每一步你可以把 当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。输入描述:输入为一个正整数N(1 ≤ N ≤ 1,000,000)
输出描述:输出一个最小的步数变为Fibonacci数"示例1: 输入: 15
输出: 2public class DemoKail { public static void main(String[] args) { int n=15; int f1=0; int f2=1; int f3=0; while(true) { f3=f1+f2; if(f3>=n) { break; } f1=f2; f2=f3; } System.out.println(f3); System.out.println(f2); int min=f3-n>n-f2?n-f2:f3-n; System.out.println(min); } }
因为他是一个斐波那契数列,所以我们需要实时计算f3的值,如果算出的f3>=n,我们就退出循环,最后发现f3-n和n-f2谁小,就返回谁
牛牛想尝试一些新的料理,每个料理需要一些不同的材料,问完成所有的料理需要准备多少种不同的材料。
输入描述:
每个输入包含 1 个测试用例。每个测试用例的第 i 行,表示完成第 i 件料理需要哪些材料,各个材料用空格隔开,输入只包含大写英文字母和空格,输入文件不超过 50 行,每一行不超过 50 个字符。
输出描述:
输出一行一个数字表示完成所有料理需要多少种不同的材料。
示例1输入
BUTTER FLOUR
HONEY FLOUR EGG
输出
4
public class DemoKail { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); HashSet<String> set=new HashSet<>(); while(scanner.hasNextLine()){ String line= scanner.nextLine(); String[] strings=line.split(" "); for(String str:strings) set.add(str); } System.out.println(1); System.out.println(set); } }
1)函数式接口:允许表达式代表功能接口
定义:
1)如果一个接口只有一个抽象方法,那么该接口就是函数式接口;
2)如果我们在接口上声明了@FunctionalIterface注解,那么编译器就会按照函数式接口的定义来要求该接口,如果有两个抽象方法,编译就会报错的,可以包含一个抽象方法,一个普通default方法,接口里面是可以写静态方法,编译器会自动地帮助我们检查函数式接口的规范
2)lamda表达式组成:
()-> {}
()表示方法中的参数列表,这里面的参数是函数式接口里面的参数,这里面的参数可以进行明确的声明而由JVM隐含的推断,只有一个推断类型的时候可以省略掉圆括号
参数列表 被引用 方法体
1)参数类型可以省略,如果要省略,就要把每个参数类型都要省略;
2)如果参数的小括号中只有一个参数,那么小括号可以省略
3)如果方法体中只有一句代码,那么大括号可以省略
4) 如果方法体只有一条语句,且是return语句,那么大括号可以省略,况且去掉return关键字
来举几个例子
1 () -> 2 没有参数返回值为2;
2 x -> 2*x 只有一个参数x,况且返回值为2*x;
3 (x,y) -> x+y; 接受两个参数,返回值为他们的和
4 (int x,int y) -> x*y;接收两个为整形的参数,返回x*y;
5 (String str) -> System.out.println(str),接收类型为String的参数,并且打印
下面我们准备好几个接口
class HelloWorld {
@FunctionalInterface
interface task1//无返回值无参数
{
void test();
}
@FunctionalInterface
interface task2//无返回值一个参数
{
void test(int a);
}
@FunctionalInterface
interface task3//无返回值多个参数
{
void test(int a, int b);
}
@FunctionalInterface
interface task4 {
int test();//有返回值,无参数
}
interface task5 {
int test(int a);//有返回值一个参数
}
interface task6 {
int test(int a, int b);//有返回值多个参数
}
1.无返回值无参数的演示
public static void main(String[] args) {
task1 t1 = () -> {
System.out.println("无返回值无参数");
};//此时可以把大括号省略,因为里面只有一条语句
t1.test();
task2 t2 = a -> {
System.out.println("无返回值一个参数");
System.out.println(a);
};
t2.test(7);
task3 t3 = (a, b) -> {
System.out.println("无返回值多个参数");
System.out.println(a + b);
};
t3.test(1, 2);
task4 t4=() ->{
System.out.println("有返回值无参数");
return 33;
};
int ret= t4.test();
System.out.println(ret);
task t5=()->10;//没有参数况且返回值是10
int a=t5.test();
System.out.println(a);
2)有返回值的情况
task4 t4=() ->{
System.out.println("有返回值多个参数");
return 33;
};
int ret= t4.test();
System.out.println(ret);
task5 t5=(int a) ->{
System.out.println("有返回值无参数");
return a*2;
};
ret=t5.test(3);
System.out.println(ret);
task6 t6=(a,b)->a+b;
ret=t6.test(2,9);
System.out.println(ret);
以前的代码可以写成这样:
PriorityQueue<Integer> queue=new PriorityQueue<>(3,(o1,o2)->o1-o2);
3)lamda表达式的变量捕获
匿名内部类的变量捕获
class HelloWorld {
static class Test
{
public void run(){
System.out.println(1);
}
}
public static void main(String[] args) {
int a=99;
new Test(){
public void run()
{
System.out.println(a);
System.out.println("我是匿名内部类,我重写了run方法");
}
}.run();
}
}
在这里只能打印a的值,不可以修改a的值
public static void main(String[] args) {
int a=100;
a=90;
Task task=new Task() {
@Override
public void Test() {
System.out.println(a);
}
};
这里面的捕获也是失败的,因为a曾经在外部被修改过,捕获的是要么没有修改过的常量,要么是这个变量被final所修饰
lamda表达式的变量捕获
class HelloWorld {
interface Task
{
public void run();
}
public static void main(String[] args) {
int a=10;
Task task=() ->{
// a=99;这里只能捕获但是不可以修改
System.out.println(a);
};
task.run();
}
}
4)lamda表达式在接口中的应用:
里面的源码是这样的:这个借口是一个函数式接口
@FunctionalInterface
public interface Consumer<T>{
void Accept(T t);
}
1)foreach-------该方法在Iterable接口中
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("扬子");
arrayList.add("蔡徐坤");
arrayList.add("姚明");
arrayList.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
可以改成这样:实现该接口,重写accept方法
ArrayList arrayList=new ArrayList<>();
arrayList.add("扬子");
arrayList.add("蔡徐坤");
arrayList.add("姚明");
arrayList.forEach(s->{
System.out.println(s);
});
foreach重要传入一个接口,里面重写accept方法
2)List 接口:里面有个方法叫做sort方法
ArrayList<String> list=new ArrayList<>();
list.add("aaaaa");
list.add("bbb");
list.add("cc");
list.add("d");
list.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
System.out.println(list);
可以改成
ArrayList<String> list=new ArrayList<>();
list.add("aaaaa");
list.add("bbb");
list.add("cc");
list.add("d");
list.sort((str1,str2) -> str1.length() - str2.length());
System.out.println(list);
}
3)Map 接口
HashMap<Integer,String> map=new HashMap<>();
map.put(1,"hello");
map.put(2,"bit");
map.put(3,"bb");
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer integer, String s) {
System.out.println(integer+"="+s);
}
});
可以改成
HashMap<Integer,String> map=new HashMap<>();
map.put(1,"hello");
map.put(2,"bit");
map.put(3,"bb");
map.forEach((k,v)->{
System.out.println(k+"="+v);
});