算法题:有1、2、3、4四个数字,能组成多少个互不相同且一个数字中无重复数字的三位数?并把他们都输出

题目

有1、2、3、4四个数字,能组成多少个互不相同且一个数字中无重复数字的三位数?并把他们都输出。

其实这题有点类似于概率问题。
只不过是把所有可能性都会列出来

我们可以首先遍历以1开头的的数字, 然后遍历以1x开头哦的数字…(x in 2,3 ,4)…

可以看出这是 O ( n n ) O(n^n) O(nn)的时间复杂度, 相当可怕。

参考代码:

class test11 {
 
    public static void main(String[] args) {
 
        int count=0;
 
        for(int i=1;i<5;i++) {
            for(int j=1;j<5;j++) {
                for(int k=1;k<5;k++) {
                    if(i!=j&&j!=k&&i!=k) {
                        count++;
                        System.out.println(i*100+j*10+k);
                    }
                }
            }
        }
        System.out.println(count);
 
    }
}

上面的槽点很多, 如果笔试时敢这么写, 面试官就一大堆问题问了。

另1个思路

我们可以直接循环100 到 999 把符合条件的数字调出来就行。

这样时间复杂度就是 O ( 1 0 n ) O(10^n) O(10n), 只需要1层循环

java代码:

public class NoDuplicatedNumbers {
    public static void main(String[] args) {
        Set<Integer> resultSet = new NoDuplicatedNumbersUnit().getResult(4);
        System.out.println(MessageFormat.format("count is {0}", resultSet.size()));
        resultSet.forEach(System.out::println);

    }
}


class NoDuplicatedNumbersUnit{
    /**
     * 
     * @param n if n = 4 , means 1,2,3,4, n must larger than 1 and smaller than 10
     * @return a number set that contains all the triple digit numbers and they are Consisted of digits up to n with no repeating digtis. e.g.  124 231 ...
     */
    public Set<Integer> getResult(int n){
        Set<Integer> resultSet = new HashSet<>();

        int start = (int) (Math.pow(10, n-2));
        int end = (int) (Math.pow(10, n-1)) - 1;

        for (int i=start; i < end + 1; i++){
            if (this.checkNumber(i, n)){
                resultSet.add(i);
            }
        }

        return resultSet;

    }

    /**
     * if one of the digit is larger than n, then return false
     * if i have duplicated digits then return false;
     * 
     * @param i a number
     * @return true of false
     */
    private boolean checkNumber(Integer i, int n){
        /*
         * chars() means to get the IntStream of ASII codes, we cannot use the elements as they are ASII codes,
         * So we need to use mapToObj() and Character.getNumericValue to convert ASII code the Integer value
         * why we use Supplier here, it's because Stream object could not execute the terminal function 2 times, to avoid 
         * "stream has already been operated upon or closed" Exception
         */

        Supplier<Stream<Integer>> streamSupplier = () -> i.toString().chars().mapToObj(Character::getNumericValue);;

        /**
         * if one of the digits large than n, then return false;
         */
        if (streamSupplier.get().anyMatch(x-> x > n)){
            return false;
        }

        /*
         * check if there's a pair of duplicated digit, if yes return false;
         */
        if (streamSupplier.get().distinct().count() < n - 1){
            return false;
        }

        return true;
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值