牛客网华为机试算法题(入门版)

350 阅读4分钟

文章目录

前言

开始掌握常用的面试中的算法。

题目一:合并表记录,集合框架,map做二维数组

概要:数据表记录包含表索引和数值(int范围的正整数),请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。

输入要求:先输入键值对的个数,然后输入成对的index和value值,以空格隔开

因为输入涉及的index和value,所以必须用到map存储起来

输出要求:输出合并后的键值对(多行)

输入示例:

4
0 1
0 2
1 2
3 4

输出示例:

0 3
1 2
3 4

代码:

import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class Test1 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);   // 用来接收输入
        while (scanner.hasNext()) {  // boolean判断
            int next = scanner.nextInt();  // 这是数量
            TreeMap<Integer, Integer> resultMap = new TreeMap();   // 自带排序器,默认为key升序,满足输出要求
            for (int i = 0; i < next; i++) {
                int key = scanner.nextInt();
                int value = scanner.nextInt();
                if (resultMap.containsKey(key)) {
                    resultMap.put(key, value + resultMap.get(key));
                } else {
                    resultMap.put(key, value);
                }
            }
            for (Map.Entry entry : resultMap.entrySet()) {  // 遍历entry=key+value   entry.getKey()   entry.getValue()
                System.out.println(entry.getKey() + " " + entry.getValue());
            }
        }
    }
}

题目二:字符串无序去重

题目描述:输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。保证输入的整数最后一位不是0。

输入描述:输入一个int型整数

输出描述:按照从右向左的阅读顺序,返回一个不含重复数字的新的整数

输入

9876673

输出

37689

代码

因为要保证有序而且不重复,所以使用了LinkedHashSet集合框架,然后倒序就倒序输出就好了

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Scanner;

public class Test2 {
    // 提取不重复整数
    // 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。
    //保证输入的整数最后一位不是0。  转换为字符串,遍历字符串中每一个字符  即去掉重复数字,如果是重复数字就丢掉
    public static void main(String[] args) {
        // 字符串无序去重需要使用什么数据结构  可以用map,用stringbuffer
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNext()){
            String string=scanner.next();
            LinkedHashSet set=new LinkedHashSet<>();
            for (int i=string.length()-1;i>=0;i--){
                set.add(string.charAt(i));
            }
            // 最后倒序打印即可
            Iterator iterator = set.iterator();
            while(iterator.hasNext()) {
                System.out.print(iterator.next());
            }
        }
    }
}

这个在牛客网上一会错一会对,不知道是不是用集合框架容量太大还是怎样,也可以用字符串

class Test2_String{
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while (scanner.hasNext()){
            String input=scanner.next();
            String[] num = input.split("");
            HashSet resultMap=new HashSet();
            StringBuffer stringBuffer=new StringBuffer();
            for (int i=num.length-1;i>=0;i--){
                if (!resultMap.contains(num[i])){
                    stringBuffer.append(num[i]);  //用stringbuffer处理结果
                    resultMap.add(num[i]);  // 用set来判断重复
                }
            }
            System.out.println(Integer.valueOf(stringBuffer+""));
        }
    }
}

问题三:字符串中字符个数统计

题目描述:编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次。例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。

输入描述:输入一行没有空格的字符串。

输出描述:输出范围在(0~127)字符的个数。

输入

abc

输出

3

仅仅统计个数,和去重一样,用个set就好了

import java.util.HashSet;
import java.util.Scanner;

public class Test3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String input = scanner.next();
            String[] nums = input.split("");
            HashSet countSet = new HashSet();
            for (int i = 0; i < nums.length; i++) {
                if (!countSet.contains(nums[i])) {
                    countSet.add(nums[i]);
                }
            }
            System.out.println(countSet.size());
        }
    }
}

凡是涉及到去重统计都可以用位图实现。因为每一个不同的数据只需要用二进制的一位存储即可,大大减小了统计所使用的存储空间

class Test3_BitSet {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String input = scanner.next();
            char[] nums = input.toCharArray();  // BitSet只能存放int和char,不能存放String,所以input.split("");变为input.toCharArray();
            BitSet countSet = new BitSet(128);
            for (int i = 0; i < nums.length; i++) {
                if (!countSet.get(nums[i])) {
                    countSet.set(nums[i]);
                }
            }
            System.out.println(countSet.cardinality());   // BitSet只能用set get cardinality ,这里不能size()
        }
    }
}

问题四:字符串倒序

题目描述:输入一个整数,将这个整数以字符串的形式逆序输出。程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001。

输入描述:
输入一个int整数

输出描述:
将这个整数以字符串的形式逆序输出

示例1
输入

1516000

输出

0006151

代码:

import java.util.Scanner;

public class Test4 {
    // 输入一个整数,将这个整数以字符串的形式逆序输出
    //程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001
    // 字符串倒序输出   直接用string就好了呀,连集合框架都免了
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while (scanner.hasNext()){
            String input = scanner.next();
            String[] exchange=input.split("");
            StringBuffer stringBuffer=new StringBuffer();
            for(int i=exchange.length-1;i>=0;i--){
                stringBuffer.append(exchange[i]);
            }
            System.out.println(stringBuffer+"");
        }
    }
}

问题五:句子逆序

题目描述:将一个英文语句以单词为单位逆序排放。例如“I am a boy”,逆序排放后为“boy a am I”
所有单词之间用一个空格隔开,语句中除了英文字母外,不再包含其他字符。

输入描述:输入一个英文语句,每个单词用空格隔开。保证输入只包含空格和字母。

输出描述:得到逆序的句子。

输入

I am a boy

输出

boy a am I

代码(两段代码都可以):

import java.util.Scanner;

//public class Test5 {
//    public static void main(String[] args) {
//        Scanner scanner=new Scanner(System.in);
//        while(scanner.hasNextLine()){   // 这里不能再以一个一个字符一个循环,要以一行为一个循环
//            String input = scanner.nextLine();   // next修改为nextLine
//            String[] nums=input.split(" ");  // 用空格分隔
//            StringBuffer stringBuffer=new StringBuffer();
//            for(int i=nums.length-1;i>=0;i--){
//                stringBuffer.append(nums[i]);
//                if (i!=0){   // 这个判断不要也过了
//                    stringBuffer.append(" ");
//                }
//            }
//            System.out.print(stringBuffer);
//        }
//    }
//}


class Test5_Help {
    // 直接输出,不要再用一个变量stringbuffer变量了
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while(scanner.hasNextLine()){   // 这里不能再以一个一个字符一个循环,要以一行为一个循环
            String input = scanner.nextLine();   // next修改为nextLine
            String[] nums=input.split(" ");  // 用空格分隔
            for(int i=nums.length-1;i>=0;i--){
                System.out.print(nums[i]+" ");
            }
        }
    }
}

问题六:字符串排序

题目描述:给定n个字符串,请对n个字符串按照字典序排列。

输入描述:输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。

输出描述:数据输出n行,输出结果为按照字典序排列的字符串。

输入

9
cap
to
cat
card
two
too
up
boat
boot

输出

boat
boot
cap
card
cat
to
too
two
up

代码

import java.util.Arrays;
import java.util.Scanner;

public class Test6 {
    // 按字典序排序  TreeSet可以做到吧
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        while (scanner.hasNext()){
            int count=scanner.nextInt();
            String[] nums=new String[count];
            for (int i=0;i<count;i++){
                nums[i] = scanner.next();   // 不断取出next,和当初C语言一样
            }
            Arrays.sort(nums);  // 用数组来完成呢个排序
            for (int i=0;i<nums.length;i++){
                System.out.println(nums[i]);
            }
        }
    }
}

尾声

都是入门级,Java写的画选好集合框架,set自带去重性质、map自带键值对、数组自带字母序方法、bitSet减少空间复杂度,刷几道掌握了就好,然后再去看二叉树、动态规划这些,一万小时定律应该是刻意学习的,而不是简单重复。

源码点击此处

天天打码,天天进步!!