Java程序员从笨鸟到菜鸟(三)算法笔试题

这篇博客主要介绍了Java程序员在面试中可能遇到的算法题,包括京东的上台阶问题、腾讯的构造回文字符串、华为的字符集合问题、组成无重复的三位数、计算字符串长度及长整数相加等,涉及递归、动态规划和HashMap等解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、上台阶(京东笔试编程题)

题目:有一楼梯共m级,刚开始时你在第一级,若每次只能跨上一级或者二级,要走上m级,共有多少走法?注:规定从一级到一级有0种走法。

给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100。为了防止溢出,请返回结果Mod 1000000007的值。

测试样例:3,返回:2

题目分析:测试样例,输入台阶数3,只有两种有效方式,也就是只能1,2或2,1,这样可以采用奇偶思想,两个1之间必须要有一个2。

思路1:采用递归方式(台阶数多的时候会超时)

代码实现:

public static int method(int n) {
    if(n > 2) 
        return (method(n - 1) + method(n - 2)) % 1000000007;
    else 
        return 1;
}

思路2:采用动态规划方法

public static int method1(int n) {
    int[] sum = new int[101];
    sum[0] = 0;
    sum[1] = 0;
    sum[2] = 1;
    sum[3] = 2;
    for (int i = 4; i <= n; i++) {
        sum[i] = (sum[i - 2] + sum[i - 1]) % 1000000007;
    }
    return sum[n];
}

运行结果:

 

二、构造回文(腾讯编程题)

题目:给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

 

对于每组数据,输出一个整数,代表最少需要删除的字符个数。

输入例子:

 

abcda

输出例子:

 

2

删除部分字符使其变成回文串问题——最长公共子序列(LCS)问题

区别:
最长公共子串(Longest Common Substirng):连续

最长公共子序列(Longest Common Subsequence,LCS):不必连续

 

思路:反序这个字符串,求新串和原串的最大子序列,需要删除的字母个数即为原字符串的长度减去最长公共子序列。

求最长公共子序列思路:假设s1字符串的下标为n1,s2字符串的下标为n2,最长公共子序列的长度为L;分两种情况:假设s1(n1) == s2(n2),那么此时最长公共子序列的长度L(n1+1,n2+1)=L(n1,n2)+1,如果s1(n1)!=s2(n2),此时要么舍弃s1的n1字符,要么舍弃s2的n2字符,这样就从L(n1,n2+1)、L(n1+1,n2)中挑选更长的子序列为最长公共子序列。

代码实现:

// 获取应删去的长度
public static int getCount(String s) {
    StringBuilder s1 = new StringBuilder(s);
    StringBuilder s2 = new StringBuilder(s).reverse();
    return s.length() - LCS(s1,s2);
}
// 求最长的公共子序列(LCS)
public static int LCS(StringBuilder s1, StringBuilder s2) {
    int n1 = s1.length();
    int n2 = s2.length();
    int[][] mutrix = new int[n1 + 1][n2 + 1];
    for (int i = 0; i < n1; i++) {
        for (int j = 0; j < n2; j++) {
            if(s1.charAt(i) == s2.charAt(j)) 
                mutrix[i + 1][j + 1] = mutrix[i][j] + 1;
            else 
                mutrix[i + 1][j + 1] = Math.max(mutrix[i][j + 1], mutrix[i + 1][j]);
        }
    }
    return mutrix[n1][n2];
}

该编程题解决思路转载来自原文传送门
 

三、字符集合(华为校招)

题目:输入一个字符串,求出该字符串包含的字符集合

输入描述:每组数据输入一个字符串,字符串最大长度为100,且只包含字母,不可能为空串,区分大小写。

输出描述:每组数据一行,按字符串原有的字符顺序,输出字符集合,即重复出现并靠后的字母不输出。

输入例子:abcqweracb

输出例子:abcqwer

思路:去除输入字符串中重复的字符,最后输出剩下的字符串。使用HashMap来处理这个问题,保存不存在的字符。

代码实现:

// 输入校验,只能输入字符,正则表达式
String regex = "^[a-zA-Z]+$";
// 求字符串包含的集合
public static StringBuilder stringSet(String s) {
    int j = 0;
    StringBuilder sb = new StringBuilder();
    HashMap<Integer, Character> hm = new HashMap<>();
    for (int i = 0; i < s.length(); i++) {
        if(!hm.containsValue(s.charAt(i))) {
            j++;
            hm.put(j, s.charAt(i));
        }
    }
    for(int n: hm.keySet()) {
        sb.append(hm.get(n));
    }
    return sb;
}

输出结果:

 

四、组成无重复的三位数

输入例子:1,2,3,4

输出结果:24 个

代码实现:

    private static void getNumber() {
        int i = 0, j = 0, k =0, n = 0;
        for (i = 1; i <= 4; i++) {
            for (j = 1; j <= 4; j++) {
                for (k = 1; k <= 4; k++) {
                    if (i != j && j != k && i != k) {
                        n  += 1;
                        Sys
                    }
                }
            }
        }
        System.out.println("共有:" + n + "个不重复的三位数");
    }

输出结果:

123
124
132
134
142
143
213
214
231
234
241
243
312
314
321
324
341
342
412
413
421
423
431
432
共有:24个不重复的三位数


Process finished with exit code 0


五、计算空格之后的字符串长度

代码实现:

private static int getWorldLength(String s) {
    return s.trim().length() - s.trim().lastIndexOf(" ") - 1;
}

输出结果:

输入的字符串: Hello world 
空格后字符串的长度为:5

Process finished with exit code 0

六、计算两个长整数之和

方式1:采用字符数组

/**
     * 求和基于字符数组
     * 可以使用类似小学做数学题,竖列按位相加,将整数每个位置的数字放入字符数组中,然后再相加
     * @param bigNumA 较大整数A
     * @param bigNumB 较大整数B
     * 时间:650ms
     * */
    private static String getResult(String bigNumA, String bigNumB) {
        char[] charA = new StringBuilder(bigNumA).reverse().toString().toCharArray();
        char[] charB = new StringBuilder(bigNumB).reverse().toString().toCharArray();
//        int maxLength = charA.length > charB.length ? charA.length:charB.length;
        int maxLength = Math.max(charA.length, charB.length);
        int[] result = new int[maxLength + 1];
        for (int i = 0; i < result.length; i++) {
            int temp = result[i];
            if (i < charA.length) {
                temp += charA[i] - '0';
            }
            if (i < charB.length) {
                temp += charB[i] - '0';
            }
            if (temp >= 10) {
                temp = temp - 10;
                result[i + 1] = 1;
            }
            result[i] = temp;
        }
        StringBuilder sb = new StringBuilder();
        boolean flag = true;
        for (int i = result.length - 1; i >= 0; i--) {
            if (result[i] == 0 && flag) {
                continue;
            }
            flag = false;
            sb.append(result[i]);
        }
        return sb.toString();
    }

方式二:采用 Math 类的 BigInteger、BigDecimal

/**
     * 使用 BigInteger 类、BigDecimal 类
     * */
    private static String getTwoSum(String s1, String s2) {
//        return new BigInteger(s1).add(new BigInteger(s2)).toString();
        return new BigDecimal(s1).add(new BigDecimal(s2)).toString();
    }

 

 

版权声明:欢迎转载, 转载请保留原文链接。https://mp.youkuaiyun.com/postedit/79354045

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值