例如, 1~13 中包含 1 的数字有 1 、 10 、 11 、 12 、 13 因此共出现 6 次
注意:11 这种情况算两次
数据范围:
进阶:空间复杂度 ,时间复杂度
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int a = 0,temp = n; int high =0,low = 0,count = 0; int[] bit = new int[6]; while(temp != 0){ bit[a++] = temp % 10; temp /= 10; } for(int i = 1; i <= a;i++){ high = n / (int)Math.pow(10,i); low = n % (int)Math.pow(10,i-1); count =count + high * (int)Math.pow(10,i-1); if(bit[i-1] > 1){ count += 1*(int)Math.pow(10,i-1); } if(bit[i-1] == 1) count += low + 1; } return count; } }
import java.util.*; public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int res = 0; for(int i = 1; i <= n; i++) { String str = String.valueOf(i); int l = str.length() - str.replaceAll("1","").length(); res+=l; } return res; } }
public static int NumberOf1Between1AndN_Solution(int n) { int cnt = 0, oldLen, newLen; String number; for (int i = 0; i <= n; i++) { number = String.valueOf(i); if (!number.contains("1")) { // 但凡能让我节省一点点的时间 continue; } oldLen = number.length(); newLen = number.replace("1", "").length(); cnt += (oldLen - newLen); } return cnt; // 超过1.49% 用Java提交的代码 }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int oneTimes = 0; for (int i = 1; i < n + 1; i++) { int num = i; while (num > 0) { if ((num - 1) % 10 == 0) oneTimes++; num = num / 10; } } return oneTimes; } }
import java.lang.Math; public class Solution { public int NumberOf1Between1AndN_Solution(int n) { String s = String.valueOf(n); int cur = 0; long digit,high,low; int res = 0; while(cur<s.length()){ char c = s.charAt(cur); digit = (long)Math.pow(10.0,s.length()-cur-1); high = n/(digit*10); if(c=='0'){ res += digit*high; } else if(c=='1'){ low = cur==s.length()-1?0: Integer.parseInt(s.substring(cur+1,s.length())); res += digit*high+low+1; } else { res += (high+1)*digit; } cur++; } return res; } }
// 来自大神路飞的思路 public int NumberOf1Between1AndN_Solution(int n) { int bit = 1, cnt = 0, low = 0, high = n / 10, cur = n % 10; while (high != 0 || cur != 0) { if (cur == 0) cnt += high * bit; else if (cur == 1) cnt += high * bit + low + 1; else cnt += (high+1) * bit; low += cur * bit; cur = high % 10; high /= 10; bit *= 10; } return cnt; }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { // 解法1:暴力 int count=0; while(n > 0){ int k=n; while(k>0){ // 看看个位是不是1 if(k%10==1) count++; // 右移一位 k/=10; } n--; } return count; } }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { // 解法2:找规律(行李箱密码锁) // 逐一计算每位数字为1的组合数目,将和相加,像转轮密码锁一样 // 比如一个3位数xxx,分别计算1xx,x1x和xx1的可能性 // 对于每一位又分3种可能,详见题解 int high = n/10; int cur = n%10; int low = 0; int factor = 1; int count=0; while( high!=0 || cur!=0){ // 当前位==0 if(cur==0) count += (high * factor); // 当前位==1 else if(cur==1) count += (high * factor+low+1); // 当前位在2~9之间 else count += ((high+1) * factor); // 更新区域和指针 low += cur*factor; factor *=10; cur = high%10; high /= 10; } return count; } }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { if (n == 0) return 0; String inputStr = String.valueOf(n); int len = inputStr.length(); int[] arr = new int[5]; int res = 0; for (int i = 1; i <= n;i++){ // 除100模10得到百位,。。。。 String tempStr = String.valueOf(i); int tempLen = tempStr.length(); for (int j = 0; j < tempLen; j++){ int a = (int)Math.pow(10,j); arr[j] = (i / a) % 10; } for (int k = 0; k < arr.length; k++){ if (arr[k] == 1){ res++; } } } return res; } }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int result = 0; int high = n / 10, cur = n % 10, base = 1, low = 0; // 从低位到高位,累加每一位为1的数的个数 while (high != 0 || cur != 0) { if (cur == 0) { result += high * base; } else if (cur == 1) { result += high * base + low + 1; } else { result += high * base + base; } low = cur * base + low; cur = high % 10; high = high / 10; base = base * 10; } return result; } }
public class Solution { public int NumberOf1Between1AndN_Solution(int n) { int count=0; for (int i = 0; i <= n; i++) { String s = Integer.toString(i); char[] chars = s.toCharArray(); for (char aChar : chars) { if(aChar=='1'){ count++; } } } return count; } }
/* 思路: 固定每一个位为1,然后看其它位一共有多少情况。 与字符串的全排列类似,但是这不是用的递归 (a+8)/10*i这个等价,很关键。(+8,等价) 举例:31456 固定百位为1 a=n/100,b=n%100 1.百位>=2,左边0~31,为32个。即为a/10+1。右边0~99,100个 所以一共(a/10+1)*i个。 2.百位=1 3.百位=0 可把分类1,2,3的前面等价为(a+8)/10. 分类2,当a%10==1时,再加上(b+1)。 */ public int NumberOf1Between1AndN_Solution(int n) { int sum = 0; //当i=10时固定十位为1,当i=1时固定个位为1 //自己举个例子,当i=1时没错 for(long i = 1;i <= n;i *= 10){ long a = n/i,b = n%i; sum += (a+8)/10*i; if(a%10==1) sum += (b+1); } return sum; }