【算法】剑指offer

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/SunshineTan/article/details/82221871

1,从1到整数n中1出现的次数

思路:若百位上数字为0,百位上可能出现1的次数由更高位决定;若百位上数字为1,百位上可能出现1的次数不仅受更高位影响还受低位影响;若百位上数字大于1,则百位上出现1的情况仅由更高位决定。
举例:
①534
这里写图片描述
个位1出现的次数:round*1+1 (每次循环1出现一次,0-9循环了53次,第54次循环为0-4)
这里写图片描述
十位1出现的次数:round*10 + 10(每次循环1出现10次,0-9循环了round=5次,第六次循环为0-3)
其他高位循环同理。
故有:

534 = (个位1出现次数)+(十位1出现次数)+(百位1出现次数)
    =(53*1+1) +(5*10+10)+(0*100+100) = 214
530 = (53*1)  +(5*10+10)+(0*100+100) = 213
504 = (50*1+1)+(5*10)   +(0*100+100) = 201
514 = (51*1+1)+(5*10+4+1)+(0*100+100) = 207
10  =  (1*1) + (0*10+0+1) = 2

代码如下:

public long CountOne(int n) {
        int count = 0; // 1的个数
        int i = 1; // 当前位
        int current = 0, after = 0, before = 0;
        while ((n / i) != 0) {
            before = n / (i * 10); // 高位
            current = (n / i) % 10; // 当前位
            after = n - (n / i) * i; // 低位
            if (current == 0)
                //如果为0,出现1的次数由高位决定,等于高位数字 * 当前位数
                count = count + before * i;
            else if (current == 1)
                //如果为1,出现1的次数由高位和低位决定,高位*当前位+低位+1
                count = count + before * i + after + 1;
            else if (current > 1)
                // 如果大于1,出现1的次数由高位决定,(高位数字+1)* 当前位数
                count = count + (before + 1) * i;
            //前移一位
            i = i * 10;
        }
        return count;
    }

2,丑数

丑数是只包含因子2、3和5的数,求从小到大的第N个丑数。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

思路一:
丑数判断:

 boolean isUgly(int number) {
        while (number % 2 == 0) number /= 2;
        while (number % 3 == 0) number /= 3;
        while (number % 5 == 0) number /= 5;
        return number == 1 ? true : false;
    }

然后依次输入每个数就可以获得N个丑数。但这样计算太多,即使一个数不是丑数,也要进行多次计算。
思路二:空间换时间,创建数组存储已经找到的丑数。后序的丑数都是min乘2或3或5得到的。
初始化数组只:{1} ;min = 1,后序 乘2或3或5,之后比较取最小值:2,3,5

    public int GetUglyNumber_Solution(int index) {
        if (index <= 0)
            return 0;
        int[] arr = new int[index];
        arr[0] = 1;
        int multiply2 = 0;
        int multiply3 = 0;
        int multiply5 = 0;
        for (int i = 1; i < index; i++) {
            int min = Math.min(arr[multiply2] * 2, Math.min(arr[multiply3] * 3, arr[multiply5] * 5));
            arr[i] = min;
            if (arr[multiply2] * 2 == min)
                multiply2++;
            if (arr[multiply3] * 3 == min)
                multiply3++;
            if (arr[multiply5] * 5 == min)
                multiply5++;
        }
        return arr[index - 1];
    }

猜你喜欢

转载自blog.csdn.net/SunshineTan/article/details/82221871