笔试强训day19

一、选择题

1、下列关于线性链表的叙述中,正确的是( )。
A 各数据结点的存储空间可以不连续,但它们的存储顺序与逻辑顺序必须一致
B 各数据结点的存储顺序与逻辑顺序可以不一致,但它们的存储空间必须连续
C 进行插入与删除时,不需要移动表中的元素
D 以上说法均不正确
他的回答: C (正确)
正确答案: C
参考答案:
一般来说,在线性表的链式存储结构中,各数据结点的存储序号是不连续的,并且各结点在存储空间中的位置关系与逻辑关系也不一致。线性链表中数据的插入和删除都不需要移动表中的元素,只需改变结点的指针域即可。
2、一个栈的初始状态为空。现将元素1,2,3,A,B,C 依次入栈,然后再依次出栈,则元素出栈的顺序是()
A 1,2,3,A,B,C
B C,B,A,1,2,3
C C,B,A,3,2,1
D 1,2,3,C,B,A
他的回答: C (正确)
正确答案: C
参考答案:
栈的修改是按后进先出的原则进行的,所以顺序应与入栈顺序相反,故选 C 。
3、下列数据结构中,不能采用顺序存储结构的是( )
A 非完全二叉树
B 堆
C 队列
D 栈
他的回答: A (正确)
正确答案: A
参考答案:
根据完全二叉树的性质 6 ,满二叉树和完全二叉树可以按层序进行顺序存储,但一般的二叉树不适用。堆可以用一维数组来存储也可以用完全二叉树来直观地表示堆的结构。队列、栈本身就是顺序存储的。故本题答案为 A 选项。
4、递归函数最终会结束,那么这个函数一定?
A 使用了局部变量
B 有一个分支不调用自身
C 使用了全局变量或者使用了一个或多个参数
D 没有循环调用
他的回答: B (正确)
正确答案: B
参考答案:
直接排除AD,注意力集中在B和C。
B肯定是对的,只有一次循环满足某个条件,不调用自己就返回,递归才会一层一层向上返回。
那么C呢,想一下,全局变量和参数确实可以用来控制递归的结束与否。
该不该选C呢?再仔细看一下题目(说实话,我很讨厌这种文字游戏),“这个函数一定…“,所以,问题集中在,是否是一定会使用这两种方式呢? 显然不是的。
除了C中提到的两种情况外,还有如下控制递归的方式:

  1. 局部静态变量是可以控制递归函数最终结束的 2. 可能通过异常来控制递归的结束。 3. 可以利用BIOS或OS的一些数据或一些标准库的全局值来控制递归过程的终止。 4. 可以把一些数据写入到BIOS或OS的系统数据区,也可以把数据写入到一个文件中,以此来控制递归函数的终止。所以,答案为B
    5、已知二叉树后序遍历序列是bfegcda,中序遍历序列是badefcg,它的前序遍历序列是:
    A abcdefg
    B abdcefg
    C adbcfeg
    D abecdfg
    他的回答: B (正确)
    正确答案: B
    参考答案:
    分析:很有代表性的一道题目,去年参加微软笔试的时候也有类似的题目。后序遍历中的最后一个元素是根节点,a,然后查找中序中a的位置,把中序遍历分成badefcg,易知左子树为b,右子树为defcg,再递归求解,可画出原始二叉树,故知前序遍历序列为B。
    6、某完全二叉树按层次输出(同一层从左到右)的序列为 ABCDEFGH 。该完全二叉树的前序序列为( )
    A ABDHECFG
    B ABCDEFGH
    C HDBEAFCG
    D HDEBFGCA
    他的回答: A (正确)
    正确答案: A
    参考答案:
    前序遍历:访问根结点在访问左子树和访问右子树之前。即先访问根结点,然后遍历左子树,最后遍历右子树;并且在遍历左子树和右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。 中序遍历:访问根结点在访问左子树和访问右子树两者之间。即先遍历左子树,然后访问根结点,最后遍历右子树。并且在遍历左子树和右子树时,仍然首先遍历左子树,然后访问根结点,最后遍历右子树。 后序遍历:访问根结点在访问左子树和访问右子树之后。即首先遍历左子树,然后遍历右子树,最后访问根结点;并且在遍历左子树和右子树时,仍然首先遍历左子树,然后遍历右子树,最后访问根结点。 完全二叉树是指除最后一层外,每一层上的结点数均达到最大值,在最后一层上只缺少右边的若干结点。 因此此完全二叉树可能的形状为: 则前序遍历序列为: ABDHECFG 。故本题答案为 A 选项。
    7、以下序列不是堆的是()
    A (100,85,98,77,80,60,82,40,20,10,66)
    B (100,98,85,82,80,77,66,60,40,20,10)
    C (10,20,40,60,66,77,80,82,85,98,100)
    D (100,85,40,77,80,60,66,98,82,10,20)
    他的回答: D (正确)
    正确答案: D
    最大堆:根节点>左右孩子
    最小堆:根节点<左右孩子
    8、设有一组记录的关键字为{19,14,23,1,68,20,84,27,55,11,10,79},用链地址法构造哈希表,哈希函数为H(key)=key MOD 13,哈希地址为1的链中有()个记录
    A 1
    B 2
    C 3
    D 4
    他的回答: C (错误)
    正确答案: D
    9、假设你只有100Mb的内存,需要对1Gb的数据进行排序,最合适的算法是?
    A 归并排序
    B 插入排序
    C 快速排序
    D 冒泡排序
    他的回答: A (正确)
    正确答案: A
    外部排序:内存中放不下所有要排序的数据,需要借助外部空间(磁盘)进行排序
    多路归并排序。
    1GB分为大小相等的20份,每份大 然后在外部空间进行
    小为50MB,依次将每份数据读入内存中进 这20份的归并过程
    行排序(内部排序:快排等)
    10、某系统总体结构如下图所示, 该系统结构图的深度是( )
    在这里插入图片描述
    A 4
    B 3
    C 2
    D 1
    他的回答: A (正确)
    正确答案: A
    参考答案:
    系统结构图的深度是指表示控制的层数。从图中可见该系统结构的深度为 4 层。故本题答案为 A 选项。

二、编程题

【汽水瓶】
某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。
小张手上有n个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。
数据范围:输入的正整数满足1<=n<=100
注意:本题存在多组输入。输入的 0 表示输入结束,并不用输出结果。

输入描述:
输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。

输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
示例1:
输入
3
10
81
0
输出
1
5
40
牛客网ACM模式代码

import java.util.*;
public class Main{
   public static int getNum(int num){
//累加汽水的个数
       int sum = 0;
//while(num > 0) 死循环
       while(num > 1){
//兑换的汽水的个数 /3
       sum += num / 3;
//剩余的空瓶子 /3 + %3
       num = num / 3 + num % 3;
         if(num == 2){
//借一瓶
            ++sum;
            break;
         }
     }
    return sum;
    }
    public static void main(String[] args){
       Scanner s = new Scanner(System.in);
        int num;
        while((num = s.nextInt()) != 0){
            System.out.println(getNum(num));
        }
    }
}

【查找两个字符串a,b中的最长公共子串】
查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。
注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开!
数据范围:字符串长度1<=length<=300
进阶:时间复杂度:O(n^3) ,空间复杂度:O(n)
输入描述:
输入两个字符串
输出描述:
返回重复出现的字符

示例1:
输入
abcdefghijklmnop
abcsafjklmnopqrstuvw
输出
jklmnop

【解题思路】
本题需要用动态规划求解,MCS[i][j]记录短字符串 s1 前 i 个字符和长字符串 s2 前 j 个字符的最长子串的长度,初始化所有值为 0。当 s1[i-1] = s2[j-1]时,MCS[i][j] = MCS[i - 1][j - 1] + 1,这里使用一个额外的值start 来记录最长子串在短字符串 s1 中出现的起始位置,maxlen记录当前最长子串的长度,当MCS[i][j] >maxlen 时,maxlen = MCS[i][j], 则start = i - maxlen ;档s1[i-1] != s2[j-1]时不需要任何操作,最后获取substr(start, maxlen)即为所求。
在这里插入图片描述
在这里插入图片描述

import java.io.*;
import java.util.*;
    public class Main{
        //假设str1长度短
        public static String getMaxSubstr(String str1, String str2){
                char[] arr1 = str1.toCharArray();
                char[] arr2 = str2.toCharArray();
                int len1 = arr1.length;
                int len2 = arr2.length;
                //最长子串的起始位置
                int start = 0;
                //最长子串的长度
                int maxLen = 0;
                //多增加一行一列,作为辅助状态
                //状态: 以a的第i个字符结尾和以b的第j个字符结尾的最长公共子串的长度
                int[][] maxSubLen = new int[len1 + 1][len2 + 1];
                for(int i = 1; i <= len1; ++i){
                    for(int j = 1; j <= len2; ++j){
                        //如果第i个字符和第j个字符相等,则进行累加
                        if(arr1[i - 1] == arr2[j - 1]){
                            maxSubLen[i][j] = maxSubLen[i - 1][j - 1] + 1;
                            //更新
                            if(maxLen < maxSubLen[i][j]){
                                maxLen = maxSubLen[i][j];
                                start = i - maxLen;
                            }
                        }
                    }
                }
            return str1.substring(start, start + maxLen);
        }
        public static void main(String[] args) throws Exception{
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                String str1;
                String str2;
                while((str1 = reader.readLine()) != null){
                        str2 = reader.readLine();
                        if(str1.length() < str2.length()){
                        System.out.println(getMaxSubstr(str1, str2));
                        }else{
                            System.out.println(getMaxSubstr(str2, str1));
                            }
                        }
                }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值