最近一個朋友通過了華為的面試,需要去參加華為機試,具體什么崗位我就不說了,說年薪可以達到35~40萬元,當然了,拿這個年薪在華為應該算是一般水平了,但是相比社會上的其他企業,這樣的工資還是蠻吸引人的,回來的時候,給我們分享了一下機試的題目。
題目描述
給定一串字符,里面有些字符有連續出現的特點,請尋找這些連續字符串中最長的串,如果最長的串有多個,請輸出ascii最小的一串?
測試字符串
321,23322a1,12fffdddaa23
答題要求
答題時間限制在90分鍾以內,不可以上網查詢,可以使用Java/Python/C#等任何語言實現。
解題思路
從第一個字符開始,遍歷循環每一個字符,利用maxBegin和maxEnd來記錄當前連續出現的子字符串的起始位置,如果當前字符串長度大於歷史最大字符串長度,或者兩者長度一樣,但當前的字符串ASCII碼小於之前的,就要用當前的字符串覆蓋歷史最長的字符串,這里要注意最后一個字符的邊界問題。
當我這個朋友在給我們分享面試題目的時候我還在想,就這么一道題還需要90分鍾嗎?如果開發環境具備,半個小時肯定搞定,於是晚上回家以后,打開電腦思考編寫,果然半個小時沒有搞定,折騰了一個小時才搞定,具體代碼如下:
public class CalcFunc {
public static String MaxRepeatString(String str){
if(str==null||str.trim().length()==0){
return "";
}
if(str.length()<2){
return str;
}
int maxBegin = 0;
int maxEnd = 1;
char [] charString = str.toCharArray();
String tempStr = "";
String maxLenStr = "";
for(int i=0;i<charString.length-1;i++){
maxEnd = i+1;
if(charString[i]==charString[i+1]){
tempStr = str.substring(maxBegin, maxEnd+1);
}else {
tempStr = str.substring(maxBegin, maxEnd);
maxBegin = maxEnd;//不相等時,改變截取字符串的開始位置
}
if(tempStr.length()>maxLenStr.length()){
maxLenStr = tempStr;
}else if(tempStr.length()==maxLenStr.length()&&maxLenStr.length()>0){
if((int)(tempStr.charAt(0))<(int)(maxLenStr.charAt(0))) {
maxLenStr = tempStr;
}
}
if(maxEnd==charString.length-1){//最后一次遍歷,並且
if(maxLenStr.length()==1){
if((int)(charString[charString.length-1])<(int)(maxLenStr.charAt(0))) {
maxLenStr = String.valueOf(charString[charString.length-1]);
}
}
}
}
return maxLenStr;
}
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String st = input.nextLine();
System.out.println(MaxRepeatString(st));
}
}
在做完上述題目以后,通過百度搜索了一下華為的機試題,發現還有其他類似的機試題,下面是我整理的幾道機試題及實現方式。
一、題目一
題目描述
在字符串中找出連續最長的數字串,並把這個串的長度返回。如果存在長度相同的連續數字串,返回最后一個連續數字串。
解題思路
遍歷該字符串每一個字符,判斷當前字符是否為數字(可以通過獲取該字符的ASCII或者使用正則表達式來判斷是否是數字),如果當前字符是數字,則從上次出現非數字字符的位置(初始為0)截取到該字符,與當前最大長度的數字串相比較,如果大於等於當前最長的字符串,則當前字符串是最大長度的字符串。
特別說明
數字串只需要是數字組成的就可以,並不需要順序,比如數字串“1234”的長度小於數字串“1359055”,如果沒有數字,則返回空字符串而不是NULL!(說明:不需要考慮負數)
實現代碼如下
public class CalcFunc {
public static String MaxLenDigitString(String str){
String maxLenDigitStr = "";
int begin = 0,end = 0;
String tempStr = "";
for(int i=0;i<str.length();i++){
end = i+1;
int chr = str.charAt(i);
if(chr>=48 && chr<=57){
tempStr = str.substring(begin,end);
}else{
begin = end;
}
if(tempStr.length()>=maxLenDigitStr.length()){
maxLenDigitStr = tempStr;
}
}
return maxLenDigitStr;
}
public static void main(String[] args) {
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String st = input.nextLine();
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("開始計算時間:"+dateFormat.format(calendar.getTime()));
String result = MaxLenDigitString(st);
System.out.println(result);
System.out.println(result.length());
dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("結束計算時間:"+dateFormat.format(calendar.getTime()));
}
}
}
二、題目二
題目描述
找出輸入字符串中的重復字符,再根據ascii把重復的字符從小到大排序
解題思路
遍歷一遍字符串數組,建立一個輔助的TreeMap,里面key=字符 value=字符個數,排序就是TreeMap會默認按鍵的ascii從小到大排列,省去排序的部分,最后就把value>1的輸出就完事了
實現代碼
public class CalcFunc{
public static String GetRepeatCharByASCII(String str){
String maxLenDigitStr = "";
StringBuffer buf=new StringBuffer();
char[] chars = str.toCharArray();
TreeMap<Character, Integer> map = new TreeMap<Character, Integer>();
for(int i=0;i<str.length();i++)
if(!map.containsKey(chars[i]))
map.put(chars[i], 1);
else
map.put(chars[i],map.get(chars[i])+1);
Iterator<Character> iterator = map.keySet().iterator();
Character key;
while (iterator.hasNext()) {
key = iterator.next();
if(map.get(key)>1)
buf.append(key);
}
maxLenDigitStr =buf.toString();
return maxLenDigitStr;
}
public static void main(String[] args) {
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String st = input.nextLine();
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("開始計算時間:"+dateFormat.format(calendar.getTime()));
String result = GetRepeatCharByASCII(st);
System.out.println(result);
System.out.println(result.length());
dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("結束計算時間:"+dateFormat.format(calendar.getTime()));
}
}
}
三、題目三
題目描述
給定一個字符串,里面會有連續重復出現的字符,比如aabbbcddeaf,要求把連續重復的字符只保留一個,比如上面的字符串處理之后就變成了abcdeaf。
解題思路
比較當前字符與前一個字符是否相等,如果相等就刪除前一個字符,不相等則直接向下遍歷
實現代碼
public class HelloWorld {
public static String GetRepeatChar(String str){
String maxLenDigitStr = "";
StringBuffer newstring =new StringBuffer(str);
for(int i=1; i < newstring.length();i++){
if(newstring.charAt(i) == newstring.charAt(i-1)){
newstring.deleteCharAt(i-1);
i--;
}
}
maxLenDigitStr = newstring.toString();
return maxLenDigitStr;
}
public static void main(String[] args) {
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String st = input.nextLine();
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("開始計算時間:"+dateFormat.format(calendar.getTime()));
String result = GetRepeatChar(st);
System.out.println(result);
System.out.println(result.length());
dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("結束計算時間:"+dateFormat.format(calendar.getTime()));
}
}
}
四、題目四
題目描述
將給定字符串去掉重復的字符后,按照字符ASCII碼順序從小到大排序后輸出,如ad2f3adjfeainzzzv,輸出23adefijnvz
代碼實現
public class HelloWorld {
public static String GetRepeatChar(String str){
String maxLenDigitStr = "";
StringBuffer buf=new StringBuffer();
char[] chars = str.toCharArray();
TreeMap<Character, Integer> map = new TreeMap<Character, Integer>();
for(int i=0;i<str.length();i++)
if(!map.containsKey(chars[i]))
map.put(chars[i], 1);
else
map.put(chars[i],map.get(chars[i])+1);
Iterator<Character> iterator = map.keySet().iterator();
Character key;
while (iterator.hasNext()) {
key = iterator.next();
//if(map.get(key)<2)
buf.append(key);
}
maxLenDigitStr =buf.toString();
return maxLenDigitStr;
}
public static void main(String[] args) {
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String st = input.nextLine();
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("開始計算時間:"+dateFormat.format(calendar.getTime()));
String result = GetRepeatChar(st);
System.out.println(result);
System.out.println(result.length());
dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("結束計算時間:"+dateFormat.format(calendar.getTime()));
}
}
}
五、題目五
題目描述
給出n對字符串,找到每對字符串中最大公共子串。
示例
2 //表示有2組
fsjdfgjs //第一組
fdfg
fdslkdfj //第二組
fjdkdfs
輸出格式:
3 //第一組,最大公共字串dfg
3 //第二組,最大公共子串kdf
解題思路
找到較短的字符串,然后從中依次取子串,這個依次取子串有點講究,要先取最長的然后慢慢減短,這使得如果找到就是最長的公共子串;在將子串依次與較長的字符串比較,如果包含則為最長公共子串
代碼實現
public class HelloWorld {
// 兩個字符串中最大的公共子串
public static String Max(String s1, String s2) {
String max = (s1.length() > s2.length()) ? s1 : s2;
String min = max.equals(s1) ? s2 : s1;
for (int i = 0; i < min.length(); i++) {
for (int m=0,n=min.length()-i ; n!=min.length()+1; m++, n++) {
String sub = min.substring(m, n);
if (max.contains(sub)) {
return sub;
}
}
}
return null;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String number = in.nextLine();
int num = Integer.parseInt(number);
String[] str = new String[num*2];
for(int i=0; i<num*2; i++){
str[i] = in.nextLine();
str[++i] = in.nextLine();
}
String[] arr = new String[num];
int j =0;
for(int i=0; i<num*2; i++){
arr[j] = Max(str[i], str[++i]);
if(arr[j] == null){
System.out.println(0);
}else{
System.out.println(arr[j].length());
}
j++;
}
}
}
六、題目六
題目描述
找出一個字符串中連續出現次數最多且長度最長的的子串,,輸出該字符串並輸出該字字符串出現的次數。
示例
輸入:abcabcabcde
輸出:abc,3
輸入:yyabcdabjcabceg
輸出:ab,3
輸入:abcab
輸出:ab,2
輸入:abcabd
輸出:ab,2
輸入:abcdabcdabcdabcdefg
輸出:abcd,4
代碼實現
public class HelloWorld {
public static HashMap<String,String> CalcMostSubStr(String mainStr){
HashMap<String,String> resultMap = new HashMap<String,String>();
int len = mainStr.length();
int maxCounts =1;
int counts = 1;
String maxSubStr ="";
//abcabcabcde,yyabcdabjcabceg,abcab,abcabd,abcdabcdabcdefg
for (int i = 0; i < len; i++) {//從第一個后綴數組開始
for(int k=len;k>i;k--){
String subOne = mainStr.substring(i,k);//0,6;0,5;0,4;0,3;0,2,0,1;1,6,1,5,1,4
counts = 1;
for(int j=k;j<=len-k;j++){
String subTwo = mainStr.substring(j,k-i+j);//1,6;/1,5,2,6/1,4;2,5;3,6
if(subOne.equals(subTwo)){
counts++;
}
}
//if(subOne.length()>maxSubStr.length()&&counts>maxCounts){
if(counts>maxCounts){
maxCounts = counts;
maxSubStr = subOne;
}
}
}
resultMap.put("maxSubStr",maxSubStr);
resultMap.put("maxCounts",String.valueOf(maxCounts));
return resultMap;
}
public static void main(String[] args) {
while (true) {
System.out.println("請輸入給定的字符串!");
Scanner input = new Scanner(System.in);
String Str = input.nextLine();
Calendar calendar= Calendar.getInstance();
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("開始計算時間:"+dateFormat.format(calendar.getTime()));
HashMap<String,String> resultMap = CalcMostSubStr(Str);
System.out.println(resultMap.get("maxSubStr"));;
System.out.println(resultMap.get("maxCounts"));;
dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss:SSS");
System.out.println("結束計算時間:"+dateFormat.format(calendar.getTime()));
}
}
}
各位朋友可以試試自己在不借助網絡的情況下,完成上述這些題分別需要多長時間,是否可以拿到這35萬元的年薪,歡迎大家在留言區,留下你更好的實現方法及完成時間。



