华为笔试0422
- 题目
思路
对于这道题,由于是需要排序数字字符(0~9),所以立马想到了桶排序。大概的思路如下:
- 遍历字符串中的每一个字符,如果不是数字直接下一个,如果是数字的话,对应的桶内数量加1。
- 遍历桶,从小到大将桶内的数字“倒”出来。
代码较易
时间复杂度:
遍历字符需要O(n),之后遍历桶最坏情况下是需要O(n),所以总的时间复杂度为O(n)
空间复杂度:
最坏情况下每个字符都是数字O(n)
总结
在这里总结一下,桶排序其实是一种哈希表,直接将字符的数值当做数组的下标来进行插入Hash Table,这里的散列函数或许是 “ char - ‘0’ ”,这里边和涉及到了散列表的冲突,处理冲突的方式便是将对应位置的数加1。
- 题目
思路
这个题基本上就是一个解析报文、校验报文的题目,这个与计算机网络中的各种各样的传输协议相关,或许直接称得上就是一种简单的协议。我们需要做的的是分析一段给出的报文是不是该协议的合法的报文。那在这里最简单的思路便是遍历输入报文中的每一个16进制数字,区别处理,用count来记录长度,用一个数组来存储处理过的数字。
- 首先判断第一个是否是5a,若不是报错。
- 之后的数字,如果是5a,说明到了一段报文的结束,这里进行长度域的校验(数组中的上一个与count-1比较),若长度正确并且无其他的问题,则是合法的报文,循环将报文输出,并置标志位flag为true,这里对于5a的处理分散到每个合法的报文中,在头部输出,最后的5a是否输出取决于是否有合法的报文。
- 若是5b,判断下一个是否是bb或者ba,若是count+1,同时5b bb| 5b ba入数组,否则用book标志记录出错了。这里因为5b一定是原文中的5b 或者 5a故格式是固定的,不是则错误。
- 其他的数字,直接将count+1,同时将其入数组。
代码
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
StringTokenizer tokenizer = new StringTokenizer(str);
if (!tokenizer.nextToken().equals("5a")) {
System.err.println("ERROR");
System.exit(0);
}
int count = 0;
String[] strs = new String[256];
int i = 0;
boolean flag = true;
boolean book = false;
while (tokenizer.hasMoreTokens()) {
String cur = tokenizer.nextToken();
if (cur.equals("5a")) {
if (count - 1 == Integer.parseInt(strs[--i], 16) && flag) {
System.out.print("5a ");
for (int j = 0; j <= i; j++) {
System.out.print(strs[j] + " ");
}
book = true;
}
i = 0;
flag = true;
count = 0;
}else if (cur.equals("5b")) {
strs[i++] = "5b";
cur = tokenizer.nextToken();
if (cur.equals("bb") || cur.equals("ba")) {
count ++;
strs[i++] = cur;
}else {
flag = false;
}
}else {
count ++;
strs[i++] = cur;
}
}
if (book) {
System.out.print("5a");
}
}
}
时间复杂度:
遍历每一个数字需要O(n),输出报文需要O(n),总的时间复杂度为O(n)。
空间复杂度:
需要一个256长度的数组来存储当前的报文,为O(1)。
总结
这里思路本来很平常,本来已经做出来了的,但是由于自己在C++以及Java的格式化输入以及格式化输出上存在一定的欠缺与疑惑,导致最终一直在这里徘徊。。。查了资料总结一下,对于Java,Scanner的nextLine()直接输入一行就可以了,同时还可以将16进制数当做字符串来处理,但是脑抽老想直接挨个输入16进制数。对于C++,需要不断地cin读入16进制数。
cin >> hex >> cur; cout << hex << setfill('0') << setw(2) << 0x5a << " "; if(cin.get() == '\n') break;
- 题目
第三题目前知道可能是用DFS或者DP来实现,还未成功实现。