一、选择题
(1)下列树结构中,不能采用顺序存储结构的是(A)
A.非完全二叉树
B.堆
C.队列
D.栈
二叉树中只有完全二叉树可以使用顺序表存储
(2)递归函数最终会结束,那么函数一定(B)
A.使用了局部变量
B.有一个分支不调用自身
C.使用了全局变量或使用了一个或多个参数
D.没有循环调用
考察递归的终止条件,终止条件所处的分支一定是不会调用自身的
换句话说,如果递归函数的所有分支都调用自身,那么该递归函数是无法终止的
(3)假设你只有100MB的内存,需要对1GB的数据进行排序,最合适的算法是(A)
A.归并排序
B.插入排序
C.快速排序
D.冒泡排序
外部排序: 内存放不下所有要排的数据,需要借助外部空间(磁盘)进行排序,多路归并排序
将1GB分为等20份,每份50MB,依次将每份数据读入内存进行内部排序,然后在外部空间进行这20份的归并过程
二、编程题
2.1 最长公共子串(动态规划)
2.1.1 题目
2.1.2 题解
dp[i][j]含义:以str1第i个字符作为公共子串的最后一个字符,以str2第j个字符作为公共子串的最后一个字符形成的公共子串的长度
状态转移方程:分两种情况
(1)如果str1的第i个字符和str2的第j个字符相等,那么dp[i][j]=dp[i-1][j-1]+1
(2)如果str1的第i个字符和str2的第j个字符不相等,那么dp[i][j]=0
初始状态:dp[0][0…str2.length()]=0,dp[0…str1.length()][0]=0
因为当str1和str2其中一个为空时,最长公共子串长度一定是0
【注意】:
- dp[i][j]中的i和j分别代码第i个字符和第j个字符,因此定义数组时长度dp[str1.length()+1][str2.length()+1]
- 同时题目要求返回的是字符串,因此我们需要使用一个变量start用来记录最长公共子串的最后一个字符的位置,用来最后的截取
代码:
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
String str1=scanner.nextLine();
String str2=scanner.nextLine();
int[][] dp=new int[str1.length()+1][str2.length()+1];
int start=0;
int max=0;
for(int i=1;i<=str1.length();i++){
for(int j=1;j<=str2.length();j++){
if(str1.charAt(i-1)==str2.charAt(j-1)){
dp[i][j]=dp[i-1][j-1]+1;
if(dp[i][j]>max){
max=dp[i][j];
start=i;
}
}
}
}
if(max==0) System.out.println(-1);
System.out.println(str1.substring(start-max,start));
}
2.2 汽水瓶
2.2.1 题目
2.2.2 题解
思路:
分析题目,三个空品可换一瓶饮料,换的一瓶饮料喝掉后就又得到一个空瓶,同时可以向老板借空瓶,但借完一定要还,这也就限制了当我们又两个空瓶的时候向老板借一个,才有能里还。
因此定义num为瓶子的数量
count为喝了多少瓶饮料
每次循环 num=num-3+1,count++ 循环的终止条件
num<2,当num=2时,可以向老板借一个空瓶后,用三个空瓶换一瓶饮料后,将喝掉后的空瓶换个老板
代码:
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
while(scanner.hasNext()){
int n=scanner.nextInt();
if(n==0) return;
int num=n;
int count=0;
while(num>=2){
num=num-3+1;
count++;
}
System.out.println(count);
}
}