作者:chicc999
链接:https://www.zhihu.com/question/26078610/answer/32110840
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
链接:https://www.zhihu.com/question/26078610/answer/32110840
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
public class Main
{
public static void main(String[] args)
{
int[] a = new int[1501];
a[1] = 1;
TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
Deque<Integer> Q2 = new ArrayDeque<Integer>();
Deque<Integer> Q3 = new ArrayDeque<Integer>();
Deque<Integer> Q5 = new ArrayDeque<Integer>();
map.put(2, 2);
map.put(3, 3);
map.put(5, 5);
for (int i = 2; i < 1501; i++) {
if (map.isEmpty())
break;
Map.Entry<Integer, Integer> e = map.pollFirstEntry();
int key = e.getKey();
int val = e.getValue();
if (val == 5) {
Q5.add(key * 5);
map.put(Q5.pollFirst(), 5);
} else if (val == 3) {
Q5.add(key * 5);
Q3.add(key * 3);
map.put(Q3.pollFirst(), 3);
} else {
Q5.add(key * 5);
Q3.add(key * 3);
Q2.add(key * 2);
map.put(Q2.pollFirst(), 2);
}
a[i] = key;
}
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
System.out.println(a[sc.nextInt()]);
}
}
}
算了前1500项,第K项存在a[K]里
大概思路就是
(1)建三个队列,Q2,Q3,Q5,存放的元素分别为2的倍数,3的倍数,5的倍数
(2)建一个容量为3的带索引的小顶堆(这里用map实现,key为值,value为标记来自哪个队列)。并将2,3,5入堆,分别来自Q2,Q3,Q5
(3)加入元素并注意优化
取堆顶元素x,如果加入堆前其来自队列Q2,则将2*x加入Q2,3*x加入Q3,5*X加入Q5。
如果加入堆前其来自队列Q3,则将3*x加入Q3,5*x加入Q5
如果加入堆前其来自Q5,则将5*x加入Q5
证明:如果x来自Q3,则设x=3t。x能被加入堆,则t一定曾经出堆(t为1的时候不成立,但不影响)。由2*t<3*t=x,2*t一定在堆里且已经出堆。由此,2*t*3已经加入堆,所以3*t*2(即2*x)无需再加入堆。Q5同理。
(4)令a[i]=x,i从2循环直至得到你需要的第K个