华为机试算法

华为机试算法思路总结

本文主要是记录一下自己的思路。如果有不对的地方,希望大家多多指正。

刷题地址

https://www.nowcoder.com/ta/huawei

算法思路

求最小公倍数

题目地址

https://www.nowcoder.com/practice/22948c2cad484e0291350abad86136c3?tpId=37&&tqId=21331&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。

输入描述:
输入两个正整数A和B。

输出描述:
输出A和B的最小公倍数。

示例1
输入
5 7
输出
35

解题思路

最小公倍数=两数之积/两个数的最大公约数

实现代码
import java.util.Scanner;

public class Main {
    public static int y(int a, int b) {
        if (a < b) {
            int tmp;
            tmp = a;
            a = b;
            b = tmp;
        } 
        int k;
        while(b != 0) {
            k = a % b;
            a = b;
            b = k;
        }
        return a;
    }
    
    public static void main(String args[]) {
        Scanner reader = new Scanner(System.in);
        while(reader.hasNext()){
            int m = reader.nextInt();
            int n = reader.nextInt();
            System.out.println(m * n / y(m, n));
        }  
    }
}

字符逆序

题目地址

https://www.nowcoder.com/practice/cc57022cb4194697ac30bcb566aeb47b?tpId=37&&tqId=21329&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
将一个字符串str的内容颠倒过来,并输出。str的长度不超过100个字符。 如:输入“I am a student”,输出“tneduts a ma I”。
输入参数:
inputString:输入的字符串

返回值:
输出转换好的逆序字符串

输入描述:
输入一个字符串,可以有空格

输出描述:
输出逆序的字符串

示例1
输入
复制
I am a student
输出
tneduts a ma I

解题思路

将字符串转换成char[],对数组进行转换。1<->n,2<->n-1等等。

实现代码
import java.util.Scanner;

public class Main {
    public static String revert(String str) {
        char[] ss = str.toCharArray();
        int j = ss.length / 2;
        for (int i = 0; i < j; i++) {
            char tmp = ss[i];
            ss[i] = ss[ss.length - 1 - i];
            ss[ss.length -1 - i] = tmp;
        }
        return new String(ss);
    }
    
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str = sc.nextLine();
            System.out.println(revert(str));
//            StringBuilder sb = new StringBuilder(str);          
//            System.out.println(sb.reverse().toString());

        }     
    }
}

字符统计

题目地址

https://www.nowcoder.com/practice/c1f9561de1e240099bdb904765da9ad0?tpId=37&&tqId=21325&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
如果统计的个数相同,则按照ASCII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。

实现以下接口:
输入一个字符串,对字符中的各个英文字符,数字,空格进行统计(可反复调用)
按照统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASII码由小到大排序输出
清空目前的统计结果,重新统计
调用者会保证:
输入的字符串以‘\0’结尾。

输入描述:
输入一串字符。

输出描述:
对字符中的
各个英文字符(大小写分开统计),数字,空格进行统计,并按照统计个数由多到少输出,如果统计的个数相同,则按照ASII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。

示例1
输入
aadddccddc
输出
dca

解题思路

将字符串转换成字符数组,遍历数组对字符进行统计,将结果放入map,对map的entrySet进行倒序排序。

代码实现
import java.util.*;

public class Main {
    public static ArrayList<Map.Entry<Character, Integer>> getStrList(String str) {
        if (str == null) {
            return null;
        }
        HashMap<Character , Integer> map = new HashMap<>();
        char[] ss = str.toCharArray();
        int length = ss.length;
        for (int i = 0; i < length; i++) {
            char key = ss[i];
            if (map.containsKey(key)) {
                int num = map.get(key);
                map.put(key, num + 1);
            } else {
                map.put(key, 1);
            }
        }

        ArrayList<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<Character, Integer>>() {
            @Override
            public int compare(Map.Entry<Character, Integer> o1, Map.Entry<Character, Integer> o2) {
                if (o2.getValue().equals(o1.getValue())) {
                    return (((int)o1.getKey() > (int)o2.getKey())) ? 1 : -1;
                }
                return o2.getValue().compareTo(o1.getValue());
            }
        });

        return list;
    }
    
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            ArrayList<Map.Entry<Character, Integer>> list = getStrList(str);
            for(Map.Entry<Character, Integer> mp : getStrList(str)){
                System.out.print(mp.getKey());
            }
            System.out.println();
        }
        sc.close();
    }
    
}

等差数列

题目地址

https://www.nowcoder.com/practice/f792cb014ed0474fb8f53389e7d9c07f?tpId=37&&tqId=21323&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
功能:等差数列 2,5,8,11,14。。。。

输入:正整数N >0

输出:求等差数列前N项和

返回:转换成功返回 0 ,非法输入与异常返回-1

本题为多组输入,请使用while(cin>>)等形式读取数据

输入描述:
输入一个正整数。

输出描述:
输出一个相加后的整数。

示例1
输入
复制
2
输出
复制
7

解题思路

等差数列求和公式:
(a1+an)n/2=(a1+a1+(n-1)d)n/2=a1n+n(n-1)*d/2

代码实现
import java.util.*;

// a1n+n(n-1)d/2
public class Main {
    public static int getSum(int n) {
        if (n < 0) {
            return -1;
        }
        
        if (n == 1) {
            return 2;
        }
        
        int sum = 2*n+n*(n-1)*3/2;
        return sum;
    }
    
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            System.out.println(getSum(n));
        }
        sc.close();
    }
}

在字符串中找出连续最长的数字串

题目地址

https://www.nowcoder.com/practice/2c81f88ecd5a4cc395b5308a99afbbec?tpId=37&&tqId=21315&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
样例输出
输出123058789,函数返回值9
输出54761,函数返回值5

接口说明
函数原型:
unsignedint Continumax(char** pOutputstr, char* intputstr)

输入参数:
char* intputstr 输入字符串;

输出参数:
char** pOutputstr: 连续最长的数字串,如果连续最长的数字串的长度为0,应该返回空字符串;如果输入字符串是空,也应该返回空字符串;

返回值:
连续最长的数字串的长度

输入描述:
输入一个字符串。

输出描述:
输出字符串中最长的数字字符串和它的长度。如果有相同长度的串,则要一块儿输出,但是长度还是一串的长度

示例1
输入
abcd12345ed125ss123058789
输出
123058789,9

解题思路

将字符串中的字符替换成“ ”,遍历数字数组,找出最长的数组,若相等,则拼接。

代码实现
import java.util.*;

public class Main {
    static int max = 0;
    public static String max(String str) {
        if (str == null || str == "") {
            return "";
        }

        String strnew = str.replaceAll("[a-zA-z]", " ");
        String[] ss = strnew.split(" ");
        max = ss[0].length();
        String result = ss[0];
        for (int i = 1; i < ss.length; i++) {
            if (ss[i].length() > max) {
                max = ss[i].length();
                result = ss[i];
            } else if (ss[i].length() == max) {
                result += ss[i];
            }
        }
        return result;
    }

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            String result = max(str);
            System.out.printf("%s,%d\n", result, max);
        }
        sc.close();
    }
}

扑克牌大小

题目地址

https://www.nowcoder.com/practice/d290db02bacc4c40965ac31d16b1c3eb?tpId=37&&tqId=21311&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王):
3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如:4 4 4 4-joker JOKER。
请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。
基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;

(4)输入的两手牌不会出现相等的情况。

输入描述:
输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如 4 4 4 4-joker JOKER。

输出描述:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。

示例1
输入
4 4 4 4-joker JOKER
输出
joker JOKER

解题思路

若字符串包含“joker JOKER”,则输出“joker JOKER”
若两边牌数相等,则比较第一位,输出第一位大的那副牌
若两边牌数不相等,则检查是否有四位(炸弹),若有则输出炸弹牌,若没有,则输出”ERROR“

代码实现
import java.util.*;

public class Main {
    public static String[] puke = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q",
            "K", "A", "2", "joker", "JOKER"};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String str = sc.nextLine();
            String[] inputs = str.split("-");
            if (inputs.length != 2) {
                System.out.println("ERROR");
                return;
            }
            String[] left = inputs[0].split(" ");
            String[] right = inputs[1].split(" ");
            int leftNum = left.length;
            int rightNum = right.length;
            int leftFlag = 0;
            int rightFlag = 0;
            if (inputs[0].equals("joker JOKER") || inputs[1].equals("joker JOKER")) {
                System.out.println("joker JOKER");
            } else if (leftNum == rightNum) {
                for (int i = 0; i < puke.length; i++) {
                    if (left[0].equals(puke[i])) {
                        leftFlag = i;
                    }
                    if (right[0].equals(puke[i])) {
                        rightFlag = i;
                    }
                }
                if (leftFlag > rightFlag) {
                    System.out.println(inputs[0]);
                } else {
                    System.out.println(inputs[1]);
                }
            } else {
                if (leftNum == 4) {
                    System.out.println(inputs[0]);
                } else if (rightNum == 4) {
                    System.out.println(inputs[1]);
                } else {
                    System.out.println("ERROR");
                    return;
                }
            }
        }
    }
}

求解立方根

题目地址

https://www.nowcoder.com/practice/caf35ae421194a1090c22fe223357dca?tpId=37&&tqId=21330&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
•计算一个数字的立方根,不使用库函数

详细描述:

•接口说明

原型:
public static double getCubeRoot(double input)

输入:double 待求解参数

返回值:double 输入参数的立方根,保留一位小数

输入描述:
待求解参数 double类型

输出描述:
输入参数的立方根 也是double类型

示例1
输入
216
输出
6.0

解题思路

二分法进行迭代,找到最接近的值。
xxx-y=0

代码实现
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            double input = sc.nextDouble();
            double min = 0;
            double max = input;
            while (max - min > 0.0001) {
                double tmp = (max + min) / 2;
                if (tmp * tmp * tmp > input) {
                    max = tmp;
                } else {
                    min = tmp;
                }
            }
            min *= 10;
            double small = min - (int)min;
            if(small >= 0.5) {
                min++;
            }
            int n = (int)min;
            min = (double)n / 10;
            System.out.println(min);
        }
    }
}

记负均正II

题目地址

https://www.nowcoder.com/practice/64f6f222499c4c94b338e588592b6a62?tpId=37&&tqId=21328&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
从输入任意个整型数,统计其中的负数个数并求所有非负数的平均值,结果保留一位小数,如果没有非负数,则平均值为0
本题有多组输入数据,输入到文件末尾,请使用while(cin>>)读入
输入描述:
输入任意个整数

输出描述:
输出负数个数以及所有非负数的平均值

示例1
输入
-13
-4
-7
输出
3
0.0

解题思路

统计负数的个数c,和非负数共和s
非负数平均值=s/(总数-c)

代码实现
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String[] str = sc.nextLine().split(" ");
            int c = 0;
            int s = 0;
            for (int i = 0; i < str.length; i++) {
                int v = Integer.valueOf(str[i]);
                if (v < 0) {
                    c++;
                } else {
                    s += v;
                }
            }
            double avg = 0;
            if (str.length > c) {
                avg = (double)s / (str.length - c);
            }
            System.out.println(c);
            System.out.printf("%.1f\n", avg);
        }
    }
}

超长正整数相加

题目地址

https://www.nowcoder.com/practice/5821836e0ec140c1aa29510fd05f45fc?tpId=37&&tqId=21301&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目要求

题目描述
请设计一个算法完成两个超长正整数的加法。

接口说明
/*
请设计一个算法完成两个超长正整数的加法。
输入参数:
String addend:加数
String augend:被加数
返回值:加法结果
*/

public String AddLongInteger(String addend, String augend)
{
/在这里实现功能/
return null;
}

输入描述:
输入两个字符串数字

输出描述:
输出相加后的结果,string型

示例1
输入
99999999999999999999999999999999999999999999999999
1
输出
100000000000000000000000000000000000000000000000000

解题思路

将输入的两个字符串先进行反转。
按位计算相同位置上的两个字符的和,放入StringBuffer中。字符相加规则:‘3’ + ‘0’ = 3
c.append(sum % 10); 取模获得本位上的数
r = sum / 10; 余数加入到下次循环中,即进位
最后将结果进行反转。

代码实现
import java.util.Scanner;

public class Main {
        public static String AddLongInteger(String a, String b) {
        StringBuffer c = new StringBuffer();
        StringBuffer sa = new StringBuffer(a).reverse();
        StringBuffer sb = new StringBuffer(b).reverse();
        int N = Math.max(sa.length(), sb.length());
        int r = 0;

        for (int i = 0; i < N; i++) {
            int bit1 = sa.length() > i ? sa.charAt(i) - '0' : 0;
            int bit2 = sb.length() > i ? sb.charAt(i) - '0' : 0;
            int sum = r + bit1 + bit2;
            c.append(sum % 10);
            r = sum / 10;
        }
        if (r > 0)
            c.append(r);

        return c.reverse().toString();
    }
    
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            String a = sc.nextLine();
            String b = sc.nextLine();
            System.out.println(AddLongInteger(a, b));
        }
        sc.close();
    }
}

判断一个数是否为质数

代码实现
public static boolean isPrimeNumber(int num) {
	if (num == 2) {
		return true;
	}
	if (num < 2 || num % 2 == 0) {
		return false;
	}
	for (int i = 3; i < Mat.sqrt(num); i+=2) {
		if (num % i == 0) {
			return false;
		}
	}
	return true;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值