zoukankan      html  css  js  c++  java
  • leetcode| Count Numbers with Unique Digits

    Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n.

    Example:
    Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding [11,22,33,44,55,66,77,88,99])

    题目:意思很明确,找出0 到10的n次方内没有重复数字构成的元素个数,11,101这类都不合格

    思路:这道题目十分具有代表性,暴力解法当然是可以的,但是根据题目标签的提示,可以用backtrack和dynamic programming,这个两个算法很值得深入学习一番,看到许多书籍提到过

    1,首先是backtrack,学名回溯算法,基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

    下面解法的思路是,对给定的数的范围0 ≤ x < 10^n,我们先区间内求1打头的,接着求2打头的.....到9打头的符合规则的数的数量,1打头里面

    我们分别求11,12,13....19打头的,如此递归,设置一个boolean数组管理哪个数字为应该规避的,应该规避的数字设为true

    public int countNumbersWithUniqueDigits(int n) {
      if (n > 10) {
        return countNumbersWithUniqueDigits(10);
      }
      int count = 1; // x == 0
      long max = (long) Math.pow(10, n);

      boolean[] used = new boolean[10];

      for (int i = 1; i < 10; i++) {
        used[i] = true;
        count += search(i, max, used);
        used[i] = false;
      }

      return count;
    }

    private static int search(long prev, long max, boolean[] used) {//查询prev打头的,范围为prev-max的个数
      int count = 0;//初始
      if (prev < max) {//递归出口
        count += 1;
      } else {
        return count;
    }

    /**
    * 这段逻辑的意思是,假设prev = 1,i=2,这时used数组中used[1]为true,used[2]为true,curr =12,再接着去查询12打头,到max为止的个数
    */
    for (int i = 0; i < 10; i++) {
      if (!used[i]) {
        used[i] = true;
        long cur = 10 * prev + i;
        count += search(cur, max, used);
        used[i] = false;
      }
    }

      return count;
    }

    2,这种思路相对而言简单好理解一点,原理是把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法

    本题中我们可以发现,这样一个规律,我们用f(n)标示n位数的符合规则元素的个数,如f(2)标识10-99区间的数目

    会发现f(n)符合这样的一个规律,f(n) = 9*9*8...(11-n),于是有如下代码

    public int countNumbersWithUniqueDigits(int n) {
      if(n==0) return 1;
        int count = 10;
        int digit = 9;
      for(int i = 2;i<=n;i++){
        digit *= (11-i);
        count+=digit;
      }
      return count;
    }

    StayHungry 求知若渴 StayFoolish 放低姿态
  • 相关阅读:
    在HTML中使用JavaScript
    七层网络模型
    JS执行机制
    继承
    变量作用域
    跨域
    ES6-Promise
    回调函数
    2019.3.9笔试
    CSS3新特性
  • 原文地址:https://www.cnblogs.com/wujunjie/p/5687677.html
Copyright © 2011-2022 走看看