【数据结构与算法】华为机试题1-3

22 阅读5分钟

1.字符串最后一个单词的长度

描述

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)

输入描述:

输入一行,代表要计算的字符串,非空,长度小于5000。

输出描述:

输出一个整数,表示输入字符串最后一个单词的长度。

示例1

输入:
hello nowcoder
输出:8

说明:
最后一个单词为nowcoder,长度为8

这里我的思路就是用空格进行切割,然后找到最后一个串,然后直接求长度,这题还是比较简单的,代码如下:

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNext()) { // 注意 while 处理多个 case
            String str = in.nextLine();
            String[] strs = str.split(" ");
            int length = strs[strs.length - 1].length();
            System.out.println(length);
        }
    }
}

随后我又去看了一下答案,发现还有另外一种也比较巧妙,直接倒着进行遍历,找到第一个空格然后输出到空格之前走了多少步,那不就是最后一个单词的长度嘛,可以可以,代码如下:

第二种解法:

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);
      String str = sc.nextLine();
      int length = str.length();
      int count = 0;
      for (int i = length - 1; i >= 0; i--) {
          if (str.charAt(i)==' ') { // 或者 if (str.substring(i, i + 1).equals(" ")) {
              break;
          }
          count++;
      }
      System.out.println(count);
  }
}

2.计算某字符出现次数

描述

写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母)

数据范围: 1n10001 \leq n \leq 1000

输入描述:

第一行输入一个由字母、数字和空格组成的字符串,第二行输入一个字符(保证该字符不为空格)。

输出描述:

输出输入字符串中含有该字符的个数。(不区分大小写字母)

示例1

输入:ABCabc
      A
输出:2

个人思路:一看题发现这个还有点意思,审审题,说白了就是输入一个串,然后再输入一个字符,然后找到你的这个字符在这个串里出现的次数,不区分大小写。

好,那就全部转成大写或者小写,然后再判断;其次该怎么解呢,想到一种就是直接把你第二个输入的字符全部给他替换成空生成一个新的串,再拿第一个串的长度减去新生成的这个串,不就是字符出现的次数了嘛,对,就这么干。(我自己并没有想到,看答案看的)

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String str1 = sc.nextLine().toLowerCase();
        String s = sc.nextLine().toLowerCase();
        int result = str1.length() - str1.replaceAll(s,"").length();
        System.out.print(result);

    }
}

第10行呢,有个replaceAll,这里呢就是把字符替换成空,作用和replace的功能一样,只不过replaceAll呢,里面可以接受正则表达式,也就是说功能稍微强大点,例如:

str.replaceAll("\\d","D")
// 这段代码的意思就是把str这个串里的数字全部替换成D。

3.明明的随机数

描述

明明生成了NN个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。

数据范围:1N10001 \leq N \leq 1000 ,输入的数字大小满足1val5001 \leq val \leq 500

输入描述:

第一行先输入随机整数的个数 N 。 接下来的 N 行每行输入一个整数,代表明明生成的随机数。 具体格式可以参考下面的"示例"。

输出描述:

输出多行,表示输入数据处理后的结果

示例1

输入:
3
2
2
1
输出:
1
2

说明:
输入解释:第一个数字是3,也即这个小样例的N=3,说明用计算机生成了31500
之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2  

思路:首先看到题目,第一个是输入一个数,代表着你接下来要输入几个数,假设输入3,接下来就代表要输入三个数,那么这三个数输完,从小到大打印出来,这里还有取重。这里立马想到了数据结构TreeSet, 可以自然排序并且去重。

import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int begin = in.nextInt();
        Set<Integer> set = new TreeSet<>();
        for(int i=0; i < begin; i++) {
            int a = in.nextInt();
            set.add(a);
        }
        set.stream().forEach(System.out::println);
    }
}

后来看了答案,我看也有这样输出的,都可以

    //输出
    Iterator iterator = set.iterator();
    while(iterator.hasNext()) {
        System.out.println(iterator.next());
    }

我自己还用了HashSet去实现,发现也是可以的,HashSet和TreeSet的区别是:

  • 1、TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值。 

  • 2、HashSet 是哈希表实现的,HashSet中的数据是无序的,可以放入null,但只能放入一个null,两者中的值都不能重复,就如数据库中唯一约束。 

  • 3、HashSet要求放入的对象必须实现HashCode()方法,放入的对象,是以hashcode码作为标识的,而具有相同内容的 String对象,hashcode是一样,所以放入的内容不能重复。但是同一个类的对象可以放入不同的实例 。