第一题:统计能整除数字的位数
题目详情
题目代码
public int countDigits(int num) {
int n = num
int ans = 0
int cur = 0
while(n != 0){ //当数字还有位数的时候进行循环
cur = n % 10
if(num % cur == 0){ //判断能不能除尽
ans++
}
n = n / 10
}
return ans
}
第二题:数组乘积中的不同质因数数目
题目详情
题目代码
public int distinctPrimeFactors(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for(int i = 0;i< nums.length;i++){
solve(nums[i] , set);
}
return set.size();
}
public void solve(int num , HashSet<Integer> set){
if(pd(num)){
set.add(num);
return;
}
for(int i = 2;i<=Math.sqrt(num);i++){
if(num % i == 0){
solve(i , set);
solve(num / i , set);
}
}
}
public boolean pd(int num){
for(int i = 2;i<=Math.sqrt(num);i++){
if(num % i == 0){
return false;
}
}
return true;
}
第三题:将字符串分割成值不超过 K 的子字符串
题目详情
题目代码
public int minimumPartition(String s, int k) {
return process(s , 0 , k);
}
public int process(String s , int index , int k){
if(index == s.length()){
return 0;
}
int i = 1;
String num = s.substring(index , index + i);
while(Long.valueOf(num) <= k && i + index < s.length()){
i++;
num = s.substring(index , index + i);
}
if(i + index == s.length() && Long.valueOf(num) <= k){
return 1;
}
if(i == 1){
return -1;
}else{
int next = process(s , index + i - 1, k);
if(next == -1){
return -1;
}else{
return next + 1;
}
}
}
代码优化
public int minimumPartition(String s, int k) {
//用来存储答案的,当然也可以优化到不用数组,用一个变量也可以完成
int[] dp = new int[s.length() + 1]
//将第一个变成1,因为如果第一个是的话,那就是1.
dp[0] = 1
//这个变量就是来记录截取字符串的大小是多少
Long num = 0L
//这个循环就是用来截取字符串的,并且判断是否合法
for(int i = 1
//这个是截取字符串
num = num * 10 + (s.charAt(i - 1) - '0')
//这个是判断是否大于指定数据
boolean flag = num > k
//这个是表示如果截取的是一位,但是还是大于的话,那就不可能截取成功,返回-1.
if(flag && num / 10 == 0){
return -1
}else if(flag){
//这个表示的是大于指定数,且不是一位。
//前一个加加,为的是防止之后一次循环的时候将后面的数据更改。因为此时,我们的i是不变的。如果下一位加上之后还是小于,那么就会导致正确的数被更改。
dp[i - 1]++
//这个就是让后面的数+1.因为大于了,所以,截取的个数是要+1的
dp[i] = dp[i - 1]
//置空
num = 0L
}
//如果乜有大于的话,那就继续往后面走,加数字
if(!flag){
dp[i] = dp[i - 1]
i++
}
}
//最后返回答案。
return dp[s.length()]
}
第四题:范围内最接近的两个质数
题目详情
题目代码
//这个表示的是最大值
private final static int NUM = (int) 1e6
//这个表示的是1到1e6中间有多少个素数
private final static int[] arr = new int[78498]
//这个静态代码块是用来初始化arr,将素数都收集起来的。
static{
//这个表示的是哪一个是素数,如果不是素数就是true,如果是素数就是false
boolean[] flag = new boolean[NUM + 1]
//这个index是素数记录到哪了。
int index = 0
//这个循环是用来遍历全部的数。
for(int i = 2
//如果之前没有数让这个格子变成true,就表示这个格子是素数
if(!flag[i]){
//记录素数
arr[index++] = i
//这个就是用来将这个数的倍数变成true,表示,只要是这个数的倍数就不是素数。
for(int j = i
flag[i * j] = true
}
}
}
}
public int[] closestPrimes(int left, int right){
//利用二分查找,找到开始的位置
int begin = find(left)
//这两个变量记录的是答案
int ans1 = -1
int ans2 = -1
//这个循环是从开始的素数,走到最后。
for(int i = begin
//如果之前没有被赋值过,或者相邻的素数相减小于原来的答案,就改变。
if(ans2 < 0 || arr[i + 1] - arr[i] < ans2 - ans1){
ans1 = arr[i]
ans2 = arr[i + 1]
}
}
return new int[]{ans1 , ans2}
}
//这个是利用二分查找找到大于等于给定值的素数。
public int find(int num){
int left = 0
int right = arr.length - 1
while(left < right){
int mid = left + (right - left)/2
if(arr[mid] > num){
right = mid
}else if(arr[mid] < num){
left = mid + 1
}else{
return mid
}
}
return left
}