给定一个数int k,将素因子只有3、5、7的数从小到大排列,返回其中第k个数。保证k小于等于100。
测试样例:
3
返回:7
/* * 时间复杂度O(N),按书中所讲,3个素数因子3、5、7分为三个队列 q3,q5,q7,其中最初存放3,5,7 * 之后每次添加找到三个队列头中最小的数,起初为3,将3移出队列 q3后,在q3添加3*3,在q5添加3*5,q7中添加3*7 * 此时可知q3{3*3},q5{5,3*5},q7{7,3*7} * 下一轮找到最小数为5,重复上述步骤,将5从q5移出,添加5*5到 q5,因为5*3已经添加过所以不需要添加到q3中 * 将5*7添加到q7,结果q3{3*3},q5{3*5,5*5},q7{7,3*7,5*7} * 依次找到第k个数 */ public int findKth(int k) { // write code here if(k < 0){ return 0; } int val = 0; Queue<Integer> q3 = new LinkedList<Integer>(); Queue<Integer> q5 = new LinkedList<Integer>(); Queue<Integer> q7 = new LinkedList<Integer>(); q3.add(1); for(int i = 0 ; i <= k; i++){ int v3 = q3.size() > 0? q3.peek() : Integer.MAX_VALUE; int v5 = q5.size() > 0? q5.peek() : Integer.MAX_VALUE; int v7 = q7.size() > 0? q7.peek() : Integer.MAX_VALUE; val = Math.min(v3, Math.min(v5,v7)); if(val == v3){ q3.remove(); q3.add(val*3); q5.add(val*5); }else if(val == v5){ q5.remove(); q5.add(val*5); }else if(val == v7){ q7.remove(); } q7.add(val*7); } return val; }
import java.util.*; /* 思路:每个数都是找三个数中最小的数*3或5或7得出来的, */ public class KthNumber { public int findKth(int k) { int [] array =new int[k]; int num3=0; int num5=0; int num7=0; array[0]=3; array[1]=5; array[2]=7; for(int i=3;i<k;i++){ array[i]=Math.min(Math.min(array[num3]*3,array[num5]*5),array[num7]*7); if(array[i]==array[num3]*3) num3++; if(array[i]==array[num5]*5) num5++; if(array[i]==array[num7]*7) num7++; } return array[k-1]; } } 运行时间:17ms 占用内存:8668k
public int findKth(int k) { // write code here int[] map = new int[k + 1]; int mul3 = 0, mul5 = 0, mul7 = 0; int result3 = 0, result5 = 0, result7 = 0; int index = 1; map[0] = 1; while (index <= k) { result3 = map[mul3] * 3; result5 = map[mul5] * 5; result7 = map[mul7] * 7; if (result3 <= result5 && result3 <= result7) { ++mul3; if (result3 > map[index - 1]) { map[index] = result3; ++index; } } else if (result5 <= result3 && result5 <= result7) { ++mul5; if (result5 > map[index - 1]) { map[index] = result5; ++index; } } else if (result7 <= result3 && result7 <= result5) { ++mul7; if (result7 > map[index - 1]) { map[index] = result7; ++index; } } } return map[k]; }
public static int findKth(int k) { // write code here int count=0; double i=3; while(count<k) { if(i%2!=0) { double b=i; while(b%3==0||b%5==0||b%7==0) { if(b%7==0) { b=b/7; } else if(b%5==0) { b=b/5; } else { b=b/3; } } if(b==1) { count++; } } i++; } return (int)i-1; }
参考了wuafeing的思路:我来解释一下,如果一个数只有3,5,7这几个素因子,那一定是满足 这样形式的,3*5*7*k,所以首先除以3,然后除以5,最后除以7,如果是符合条件的,最后肯定 就是1,可能有人会说也可能是2,3,4,5,6啊,注意到这些数只有2,4可能,因为3,5在前面 已经作为除数了,最后的结果不会有3,5了,而6呢,本质就是2。 下面提供2种思路: class KthNumber { public: int findKth(int k) { /*int num = 3; while(num && k){ int temp = num; while(temp%3 ==0) temp /= 3; while(temp%5 ==0) temp /= 5; while(temp%7 ==0) temp /= 7; if(1 == temp) k--; num++; } return --num;*/ vector<int> res(k+1); int i=0,j=0,t=0; res[0]=1; int num=0; for(int h=1;h<=k;h++)//不能从0开始,不然res[0]=3;影响第二个数5的产生 { num=min(res[i]*3,min(res[j]*5,res[t]*7)); res[h]=num; if(num==res[i]*3) i++; if(num==res[j]*5) j++; if(num==res[t]*7) t++; } return res[k]; } };
public int findKth(int k) {
LinkedList<Integer> q3 = new LinkedList<>();
LinkedList<Integer> q5 = new LinkedList<>();
LinkedList<Integer> q7 = new LinkedList<>();
q3.offer(3);
q5.offer(5);
q7.offer(7);
int index = 1;
int min = 0;
while( index<=k ){
min = Math.min(q3.peek(), Math.min(q5.peek(), q7.peek()));
if ( min==q3.peek() ) {
q3.poll();
q3.offer(min*3);
q5.offer(min*5);
q7.offer(min*7);
}
if ( min==q5.peek() ) {
q5.poll();
q5.offer(min*5);
q7.offer(min*7);
}
if ( min==q7.peek() ) {
q7.poll();
q7.offer(min*7);
}
index++;
}
return min;
}
class KthNumber { public: int findKth(int k) { // write code here int num = 3; while(num && k){ int temp = num; while(temp%3 ==0) temp /= 3; while(temp%5 ==0) temp /= 5; while(temp%7 ==0) temp /= 7; if(1 == temp) k--; num++; } return --num; } }; //类似丑数算法!最简洁的,木有之一
class KthNumber { public: int findKth(int k) { // write code here vector<int > num3,num5,num7; int i3 = 0, i5 = 0, i7 = 0,res; num3.push_back(3); num5.push_back(5); num7.push_back(7); for (int i = 0; i < k; ++i) { res = min(min(num3[i3],num5[i5]),num7[i7]); if(res == num3[i3]) i3++; if(res == num5[i5]) i5++; if(res == num7[i7]) i7++; num3.push_back(3 * res); num5.push_back(5 * res); num7.push_back(7 * res); } return res; } };
# -*- coding:utf-8 -*- class KthNumber: def findKth(self, k): # write code here queue3=[3] queue5=[5] queue7=[7] count=0 while count<k: min_s=min(queue3[0],queue5[0],queue7[0]) if min_s==queue3[0]: min_s=queue3.pop(0) queue3.append(min_s*3) queue5.append(min_s*5) elif min_s==queue5[0]: min_s=queue5.pop(0) queue5.append(min_s*5) else: min_s==queue7[0] min_s=queue7.pop(0) queue7.append(min_s*7) count+=1 return min_s
//对于合法的数,存放于队列中,开始为:3,5,7 //以当前合法的数为基础,采用淘汰机制 //淘汰的原则是队列的首个元素如果乘以7小于队列最后一个元素 //则说明该元素乘以3,5,7均已经加入队列,该元素可以淘汰 //而队列添加元素的准则是当前元素乘以3,5,7中最小的一个 class KthNumber { public: int findKth(int k) { vector<int> v{ 3, 5, 7 }; if (k <= 3) return v[k - 1]; int count = 3; while (count < k){ if (v.front() * 7 <= v.back()) v.erase(v.begin()); else{ int i = 1, min = findMinAvaliable(v[0], v.back()); while (v[i] * 3 < min && i < v.size()){ if (findMinAvaliable(v[i], v.back()) < min){ min = findMinAvaliable(v[i], v.back()); } i++; } v.push_back(min); count++; } } return *(v.end()-1); } int findMinAvaliable(int n, int key){ int min = 0; if (n * 3 > key) min = n * 3; else{ if (n * 5 > key) min = n * 5; else min = n * 7; } return min; } };
public int findKth(int k) { // write code here int[] nums = new int[k+1]; nums[0]=1; int n3=0; int n5=0; int n7=0; int index=0; while(index<k){ index++; nums[index] = min(nums[n3]*3,nums[n5]*5,nums[n7]*7); if(nums[n3]*3==nums[index]) n3++; if(nums[n5]*5==nums[index]) n5++; if(nums[n7]*7==nums[index]) n7++; } return nums[index]; } public int min(int a , int b,int c){ return Math.min(a,Math.min(b,c)); }
//思路1:题目说保证K小于100,所以就用暴力法写一下了。 class KthNumber { public: int findKth(int k) { // write code here int count=0; int i=3; while(count<k) { if(isP(i)) { count++; } i++; } return i-1; } bool isP(int number) { if(number<3) return false; while(number%3==0) number=number/3; while(number%5==0) number=number/5; while(number%7==0) number=number/7; return ((number==1)?true:false); } }; /*思路2:3,5,7满足题目要求,那么3,5,7的3倍、5倍、7倍依然是满足题目要求的; 用队列实现,代码如下。*/ class KthNumber { public: int findKth(int k) { // write code here queue<int> q3; queue<int> q5; queue<int> q7; int count=1; int i=1; while(count<=k) { q3.push(i*3); q5.push(i*5); q7.push(i*7); int min3=q3.front(); int min5=q5.front(); int min7=q7.front(); int min=((min3<min5)?min3:min5); min=((min<min7)?min:min7); if(min==min3) q3.pop(); if(min==min5) q5.pop(); if(min==min7) q7.pop(); i=min; count++; } return i; } };
public int findKth(int k) { LinkedList<Integer> l1 = new LinkedList<>(); LinkedList<Integer> l2 = new LinkedList<>(); LinkedList<Integer> l3 = new LinkedList<>(); l1.add(3); l2.add(5); l3.add(7); int val = 3; for (int i = 1; i <= k; i++) { int a = l1.peek(), b = l2.peek(), c = l3.peek(); val = Math.min(Math.min(a, b), c); if (val == a) { l1.removeFirst(); l1.add(val * 3); l2.add(val * 5); } else if (val == b) { l2.removeFirst(); l2.add(val * 5); } else l3.removeFirst(); l3.add(val * 7); } return val; }
1. 初始化结果temp=1和队列q3,q5,q7 2. 分别往q3,q5,q7插入1*3,1*5,1*7 3. 求出三个队列的队头元素中最小的那个x,更新结果res=x 4. 如果x在: q3中,那么从q3中移除x,并向q3,q5,q7插入3*x,5*x,7*x q5中,那么从q5中移除x,并向q5,q7插入5*x,7*x q7中,那么从q7中移除x,并向q7插入7*x 5. 重复步骤3-5,直到找到第k个满足条件的数
注意,当x出现在q5中,我们没往q3中插入3*x,那是因为这个数在q5中已经插入过了。
class KthNumber { public: int findKth(int k) { int num[105]; int pos3, pos5, pos7; pos3 = pos5 = pos7 = 0; num[0] = 1; for(int i = 1 ; i <= k ; i++) { num[i] = min(num[pos3] * 3, min(num[pos5] * 5, num[pos7] * 7)); if(num[i] == num[pos3] * 3) pos3++; if(num[i] == num[pos5] * 5) pos5++; if(num[i] == num[pos7] * 7) pos7++; } return num[k]; } };
# -*- coding:utf-8 -*- class KthNumber: def findKth(self, k): # write code here result = [1] i3, i5, i7 = 0, 0, 0 while len(result) < k+1: result.append(min( 3 * result[i3], 5 * result[i5],7 * result[i7],)) if result[-1] == 3 * result[i3]: i3 += 1 if result[-1] == 5 * result[i5]: i5 += 1 if result[-1] == 7 * result[i7]: i7 += 1 return result[-1]