面试趣闻,随记

本文详细解析了一个面试中遇到的算法问题——计算26个字母的所有组合,并提供了Java代码实现。通过寻找规律,作者最终得出公式并成功解决了问题。
  • 之前面试遇到一个面试官,问了我一些Android基础的知识,然后就出了两个算法题目给我:
    • 第一个,怎么使用JavaString类的split()方法。
      • 这个就不多说了,当时我也磕磕碰碰的写出来了,写出来之后,一直让我优化,搞得我大为恼火,以为是故意折腾人的。
    • 然后是一道纯粹的算法题目:有A-Z共26个字母,A是一种组合,B是一种组合,AB也是一种组合,ABC也是,XDC也是一种组合,以此类推。请使用代码实现,计算A-Z这26个字母的全部组合。
      • 这一题就惨了,当时本来就很恼火了,因为之前的String.split()一直优化的问题。现在又搞这个,真是头都大了,不知道如何去解。我想了十几分钟,然后就告诉面试官,这个真不会,然后我就挂了。
      • 今天忽然想到,这一题貌似可以使用找规律的方式去解决,于是写了一下:
26个字母的排列组合的计算:
解:
    1. 如果是1个字母A,则,组合数量sum = 1; (A)
    2. 如果是2个字母AB,则,组合数量sum  = 4; (A,B,AB,BA)
    3. 如果是3个字母ABC,则 组合数量sum = 15; (A,B,C,AB,AC,BA,BC,CA,CB,ABC,ACB,BAC,BCA,CAB,CBA)              
    4. 如果是4个字母ABCD,则 组合数量sum = ?; (A,B,C,D, AB,AC,AD, BA,BC,BD, CA,CB,CD, DA,DB,DC, ABC,ABD, ACB,ACD, ADB,ADC, BAC,BAD, BCA,BCD, BDA,BDC,...,ABCD,ABDC, ACBD,ACDB, ADBC,ADCB, )
                                                   n   +                  (n-1) *n              + (n-2)*(n-1) *(n)  +                                      (n-2)*(n-1)*(n)
                                                   n   +                  (n-1) *n              +                                                                               

    f(1) = 1;
    f(2) = 4;
    f(3) = 15;
    f(n) = ?
    //===================
    f(1) = 1;
    f(n) = n   + (n-1) *n + (n-2)*(n-1) *(n) +(n-2)*(n-1)*(n);

    f(x) = {
        if(x==1) f(x) =1;
        else
            f(x) = n   + (n-1) *n + (n-2)*(n-1) *(n) +(n-2)*(n-1)*(n);
    }

    f(2) = 2+1*2  =4;
    f(3) = 3+2*3+1*2*3 * 2 = 3+6+6 = 15;
    f(26) = 26+ 26*25+ 24*25*26 *2 = 31876

如果以上算法正确,那么答案就是31876.

但是很不幸,以上的算法是错误的。


  • 正确的做法如下:
    n个字母,每次都是1个字母参与的排序:n
    n个字母,每次都是2个字母参与的排序:n*(n-1) (AB,AC,AD,..,AZ; BA,BC,..,BZ)[第一个位置有n个可能,第二个位置有n-1]
    n个字母,每次都是3个字母参与的排序:n*(n-1)*(n-2) (ABC,ABD,ABE,ABF,...,ABZ; ACB,ACD,ACE,...,ACZ;) [第一个位置有n个可能,第二个位置有n-1,第三个位置有n-2个可能]
    ....
    n个字母,每次都是n-1个字母参与排序:n*(n-1)*(n-2)*...*(2)
    n个字母,每次都是n-1个字母参与排序:n*(n-1)*(n-2)*...*(2)*(1)
    而,全部的排序组合就是以上的相加:
    Sum(n) = f(n)+f(n-1)+ f(n-2)+...+f(2)+f(1);
    其中:f(n) = n*(n-1)*(n-2)*..(1); 

以上是算法,则代码为:(Java 实现:)

package com.pythonCat.sort;

import java.math.BigInteger;

/**
 * Created by pythonCat on 16-2-23.
 * 26个字母的任意排列组合的计算
 */
public class AbcSort {

    public static void main(String[] args) {

        AbcSort obj = new AbcSort();
        long n = 26;
        BigInteger count = obj.getSortCount(n);
        System.out.println("n = " + n + ", sortCount = " + count);

        BigInteger sortSum = obj.getSortSum(n);
        System.out.println("n = " + n + ", sortSum = " + sortSum);
    }

    /**
     * 获取n个不同字母A-Z全排列的所有组合
     * n个字母,每次都是n个字母参与排序:n*(n-1)*(n-2)*...*(2)*(1)
     *
     * @param n n个字母
     * @return
     */
    public BigInteger getSortCount(long n) {
        if (n == 1) return BigInteger.valueOf(1);//递归终止条件
        else
            return BigInteger.valueOf(n).multiply(getSortCount(n-1));//递归原则

    }

    /**
     * 获取n个不同字母A-Z任意排列的所有组合
     *
     * @param n n个字母
     * @return
     */
    public BigInteger getSortSum(long n) {

        BigInteger sum = BigInteger.valueOf(0);
        while (n > 0) {
            sum = sum.add(getSortCount(n));
            n--;
        }

        return sum;
    }


}
  • 因为上面的排序结果太大,超出了long的范围,所以使用了java.math.BigInteger类,关于此类的介绍,请参阅API或这篇博客
  • 计算结果为(26个字母的任意排序的可能–控制台输出的结果):
n = 26, sortCount = 403291461126605635584000000
n = 26, sortSum = 419450149241406189412940313

以上就是这个问题的最终答案。

开发相关随记包含多个方面: - **软件开发**:在增加和设计较为庞大的程序时,要考虑程序结构设计,如解耦、层与层接口、模块之间关系、参数、ram、flash、运行速度等。还可学习了解aoutosar的分层结构。新的项目需在较短时间完成从零编码到交付[^1]。 - **IsaacLab开发**:遇到在spring - damping模型下,调大限制和刚度、damping参数后出现异常情况,几十个episode插入后不在孔周围晃,此现象与预期不符,需进一步理顺[^2]。 - **Chrome扩展程序开发**:Map是新的数据类型,可在JavaScript中用于存储键值对实现快速查找,还给出了本地缓存工具的代码实现,同时列举了一些相关学习参考资料,如ReqBin在线API测试工具、Chrome插件开发攻略等[^3]。 ```javascript let data = new Map([ ['Alice', 25], ['Bob', 30], ['Charlie', 35], ['David', 40] ]); console.log(data.get('Alice')); // 25 var myLocalStorageTool = { set: function(key, value) { localStorage.setItem(key, value); }, get: function(key) { return localStorage.getItem(key); }, remove: function(key) { localStorage.removeItem(key); }, removeAll: function() { localStorage.clear(); }, toJsonString: function(jsData) { return JSON.stringify(jsData); }, toJsData: function(jsonString) { return JSON.parse(jsonString); } }; ``` - **X86平台开发**:对于intel的X86平台,intel提供完整数据手册和丰富资源,不同卷册有不同内容,如vol 1是整体介绍,vol 2是CPU部分寄存器说明等,还有PDG、硬件设计指南、散热文档、产线可制造性文档等可供参考[^4]。 - **通用开发问题**:client的定时器是通用功能,但依赖cocos2d的Scheduler类,导致移植到server端困难,使用C++标准库实现可避免该问题[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值