【笔试训练】排序子序列和倒置字符串

目录

一、选择题

二、倒置字符串


一、选择题

一、A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明:

1. A a0=new A();

2. A a1=new B();

3. A a2=new C();

问以下哪个说法是正确的(D

A. 只有第一行能通过编译

B. 第1、2行能通过编译,但第3行编译出错

C. 第1、2、3行能通过编译,但第2、3行运行时出错

D. 第1行,第2行和第3行的声明都是正确的


答案:选D

 因为B继承自A,C继承自B,也可以认为C继承了A。相当于你爸爸继承了你爷爷的一些特点,而你继承了你爸爸的特点,间接的你也继承了你爷爷的特点。

二、下面代码将输出什么内容:(B

public class SystemUtil{
     public static boolean isAdmin(String userId){
         return userId.toLowerCase()=="admin";
     }
     public static void main(String[] args){
         System.out.println(isAdmin("Admin"));
     }
}

 A. true    B. false     C. 1     D. 编译错误 


答案:B

字符串是一个引用类型,所以比较两个字符串是否相等需要使用equals方法,这里使用==比较,比较的是两个字符串的地址。

三、 阅读如下代码。 请问,对语句行 test.hello(). 描述正确的有(D

package NowCoder;
class Test {
     public static void hello() {
         System.out.println("hello");
    }
}
public class MyApplication {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Test test=null;
        test.hello();
    }
}

A. 能编译通过,并正确运行

B. 因为使用了未初始化的变量,所以不能编译通过

C. 以错误的方式访问了静态方法

D. 能编译通过,但因变量为null,不能正常运行


答案:D

这里是因为hello是属于类的方法,不能借助对象来调用,但是这个引用指向的对象为null,

所以这里test调用hello方法,是可以执行的,并没有借助对象来调用。

四、下列哪一种叙述是正确的(D

A. abstract修饰符可修饰字段、方法和类

B. 抽象方法的body部分必须用一对大括号{ }包住

C. 声明抽象方法,大括号可有可无

D. 声明抽象方法不可写出大括号


答案:D

abstract可以修饰类和方法,但是不能修饰成员变量。

声明抽象方法,有访问限定修饰符、返回值类型、方法名,但是不能有方法体,也就是{}。

五、如下代码的执行结果是什么(B

class Base {
     Base() {
         System.out.print("Base"); 
     }
}
public class Alpha extends Base {
     public static void main( String[] args ) {
         new Alpha();
         //调用父类无参的构造方法
         new Base();
     } 
}

 A. Base    B. BaseBase     C. 编译失败      D. 代码运行但没有输出     E. 运行时抛出异常


答案B

因为在创建子类继承父类的时候,即使子类中没有写构造方法,在创建子类对象的时候,调用的无参构造方法,也会首先调用父类的构造方法,先执行父类的构造方法,然后再执行子类的构造方法。

六、如下代码的执行结果是什么(D

public class Test { 
     public int aMethod(){
         static int i = 0;
         i++; 
         return i;
     } 
    public static void main(String args[]){
         Test test = new Test(); 
         test.aMethod(); 
         int j = test.aMethod();
         System.out.println(j);
     } 
}

A. 0       B. 1       C. 2        D. 编译失败 


答案:D

静态的变量只能再类中,或者静态方法、或者静态代码块中定义,不能再非静态的方法或者代码块中定义,因为静态的变量属于类,而给静态的方法和代码块通过实例化对象,就会属于某个对象。

二、倒置字符串

 【解题思路】:这里我们将输入的字符串转换成字符数组,然后整体将字符数组中的元素逆置,然后再将每个单词进行逆置,这样就得到了一个逆置之后的字符串。

public class Main{
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String str = scan.nextLine();
        char[] ch = str.toCharArray();
        int let = ch.length;
        //将整体的字符串进行逆置
        func(ch,0,let-1);

        int i = 0;
        while(i < let){
              int j = i;//i用来遍历数组中的单词
            //当j小于数组长度并且j指向的位置不是空格,则向前挪动一位。
            while(j < let && ch[j]!= ' '){
                j++;
            }
            //当j没有走到数组末尾之后,则对空格之前的单词进行逆置
            if(j < let){
                func(ch,i,j-1);
                i = j+1;
            }else{
                //如果j走到最后数组最后一个元素之后,则表示这个数组中每个单词已经逆置完了,将i和j放在同一个位置,用i作为循环结束条件。
                func(ch,i,j-1);
                i = j;
            }
        }
        String string = new String(ch);
        System.out.println(string);
    }
    public static void func(char[] array,int start,int end){
        while(end>start){
            char tmp = array[start];
            array[start] = array[end];
            array[end] = tmp;
            //两个指针移动到下一个需要交换的位置,进行下一组交换。
            start++;
            end--;
        }
    }
}

三、排序子序列

牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道它最少可以把这个数组分为几段排序子序列。

如阳历所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分2个排序子序列,所以输出2.

输入描述:输入的第一行为一个正整数n(1 ≤ n ≤ 10^5),第二行包括n个帧数A_i(1 ≤ A_i ≤ 10^9),表示数组A的每个数字。

输出描述:输出一个整数表示牛牛可以将A最少划分为多少段排序子序列

示例

输入6

1 2 3 2 2 1

输出 2

 题目分析

递增排列:1,2,3,4,5;也就是a[ i ] < a[ i+1 ]

递减排列:9,8,7,6,5;也就是a[ i ] > a[ i+1 ]

非递减排列:1,2,2,3,3,5,6;也就是a[ i ] <= a[ i+1 ]

非递增序列:9,8,7,5,5,3,2;也就是a[ i ] >= a[ i+1 ]

  • 非递增和非递减排列整体还是呈现递减或者递增,但是中间存在相同的数。
  • 上述题目表示的意思为,你输入的一组数字,可以按照非递增或者非递减的方式分为几组。你输入的这组数字,可能存在连续几个数字是非递增,这几个数字之后,又存在一些数字是连续非递减的。

✨当我们定义一个变量i遍历你输入的这个数组,存在三种情况

  1. i遍历到的数字,比i+1位置的数字小,
  2. i遍历到的数字,比i+1位置的数字大,
  3. i遍历到的数字,与i+1位置的相等。

代码示例

public class Main{
    public static void main(String[] args) {
        Scanner scan =new Scanner(System.in);
        int n = scan.nextInt();//定义的输入元素的个数
        int[] arr = new int[n+1];//这里给数组定义的长度比输入的大1,是因为防止遍历数组进行比较的时候,出现数组越界。
        for (int i = 0; i < n; i++) {
            arr[i] = scan.nextInt();
        }
        int count = 0;//用来记录划分的子序列的个数
        int i = 0;//使用i遍历数组
        //这里使用循环,因为i没向前做一步,都需要判断是否到元素的末尾,并且判断是三种情况中的哪一个
        while(i < n){
            if(arr[i] < arr[i+1]){
                //i下标的值比i+1小
                while(i < n && arr[i] < arr[i+1]){
                  //有可能存在一些值连续情况下都是i下标的值比i+1的小,将这种情况的一组数据遍历完就需要使用一个变量记录一下,
                    //这就是数组划分的一个子序列。
                  i++;
                }
                count++;
                //这里使用i++,例如 123221,当i在3的位置时,没有满足if条件,所以3之前包括3,被划分为一个子序列,就需要i在向前走一位。
                i++;

            }else if(arr[i] == arr[i+1]){
                //i下标的值和i+1的值相等
                i++;
            }else{
                //i下标的值比i+1的值大
                while(i < n && arr[i] > arr[i+1]){
                    //也有可能出现一组连续的数字i位置的值比i+1位置的值大,这种情况的一组数据遍历完成之后,就需要记录一下。
                    //这就是 数组划分的有一个子序列
                    i++;
                }
                count++;
                i++;
            }
        }
        System.out.println(count);
    }
}

图解代码中对数组越界的处理

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值