数学(第三十一天——困难)
- 第一题:[剑指 Offer 14- II. 剪绳子 II](https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/)
- 第二题:[剑指 Offer 43. 1~n 整数中 1 出现的次数](https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/)
- 第三题:[剑指 Offer 44. 数字序列中某一位的数字](https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/)
第一题:剑指 Offer 14- II. 剪绳子 II
问题描述
思路
之前有个一样的剪绳子的问题,思路都差不多。说一个关键点:这个问题说了有大数的情况,为了避免大数的越出的情况,因此用模的方法来避免大数越界的情况;具体看代码。
代码
class Solution {
public int cuttingRope(int n) {
if(n<=3) return n-1;
long res = 1;
while(n > 4){
res *= 3;
res %= 1000000007;
n -= 3;
}
return (int)(res * n % 1000000007);
}
}
时间空间复杂度
第二题:剑指 Offer 43. 1~n 整数中 1 出现的次数
问题描述
思路
这个思路有点复杂,形象的比喻就是一个自行车的那个密码锁,有0-9的数字,进行全部的组合有多组合,还是给大家看大佬的代码,能够更清晰的理解和观察。
解题思路:
作者:jyd
链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/solution/mian-shi-ti-43-1n-zheng-shu-zhong-1-chu-xian-de-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码
class Solution {
public int countDigitOne(int n) {
int digit = 1,count = 0;
int high = n /10,cur = n %10,low = 0;
while(cur != 0 || high != 0){
if(cur == 0)
count += high*digit;
else if(cur ==1)
count += high*digit+low+1;
else
count += (high+1)*digit;
low +=cur*digit;
cur =high %10;
high /= 10;
digit *= 10;
}
return count;
}
}
时间空间复杂度
第三题:剑指 Offer 44. 数字序列中某一位的数字
问题描述
思路
/* 数字范围 数量 位数 占多少位
1-9 9 1 9
10-99 90 2 180
100-999 900 3 2700
1000-9999 9000 4 36000 ...
例如 2901 = 9 + 180 + 2700 + 12 即一定是4位数,第12位 n = 12;
数据为 = 1000 + (12 - 1)/ 4 = 1000 + 2 = 1002
定位1002中的位置 = (n - 1) % 4 = 3 s.charAt(3) = 2;
*/
代码
class Solution {
public int findNthDigit(int n) {
int digit = 1; // n所在数字的位数
long start = 1; // 数字范围开始的第一个数
long count = 9; // 占多少位
while(n > count){
n -= count;
digit++;
start *= 10;
count = digit * start * 9;
}
long num = start + (n - 1) / digit;
return Long.toString(num).charAt((n - 1) % digit) - '0';
}
}
时间空间复杂度
结尾
此次的刷题就暂告一段落,后面会写一篇总结自己的刷题的理解和心得感悟以及经验,来巩固自己的刷题的过程。