题目
题目链接:
https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b
思路
注意: 数据范围:0≤n≤2000, 2000肯定到不了,最多到1690,相同题目链接:https://www.lintcode.com/problem/4。
思路,从小到大依次把丑数列出来,存入优先级队列
参考答案Java
import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param index int整型* @return int整型*/public int GetUglyNumber_Solution (int index) {//n最多到1690,题目给的到不了2000,if(index ==0) return 0;PriorityQueue<Long> pq = new PriorityQueue<>();for (long i = 1; i <= 0x7fffffff ; i *= 2) {for (long j = i; j <= 0x7fffffff ; j *= 3) {for (long k = j; k <= 0x7fffffff; k *= 5) {pq.add(k);}}}while (index > 1) {pq.poll();index--;}long s = pq.poll();return (int)s;}
}
参考答案Go
package main/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param index int整型* @return int整型*/
func GetUglyNumber_Solution(index int) int {//Go的优先级队列,或者叫堆,需要自己实现if index ==0 {return 0}h := newHeap02(true)for i := 1; i <= 0x7fffffff; i *= 2 {for j := i; j <= 0x7fffffff; j *= 3 {for k := j; k <= 0x7fffffff; k *= 5 {h.add(k)}}}for index > 1 { //升序优先级队列中要保留一个h.remove()index--}return h.remove()
}type Heap02 struct { //heap的定义Array []intSize intDefaultSize intAsc bool //true: 升序 false 降序
}func newHeap02(asc bool) Heap02 {return Heap02{Array: make([]int, 10), Size: 0, DefaultSize: 10, Asc: asc}
}func (h *Heap02) ensureSize(length int) { //扩容代码oldsize := len(h.Array)if oldsize >= length {return}//新增容量为旧容量的1.5倍newSize := oldsize + oldsize>>1newArr := make([]int, newSize)for i := 0; i < h.Size; i++ {newArr[i] = h.Array[i]}h.Array = newArr
}
func (h *Heap02) add(val int) { //新增oldSize := h.Sizeh.ensureSize(oldSize + 1)h.Array[oldSize] = valh.Size++//fmt.Println(h.Array, " is idx ")h.siftUp(oldSize)
}func (h *Heap02) siftUp(idx int) { //上滤,大顶堆cur := h.Array[idx]for idx > 0 {//fmt.Println(idx, " is idx ")pindex := (idx - 1) / 2parent := h.Array[pindex]if !h.Asc {if parent >= cur {break}} else {if parent <= cur {break}}h.Array[idx] = parentidx = pindex}h.Array[idx] = cur//fmt.Println(idx, " is idx ")
}// 删除:二叉堆的删除是删除堆顶元素
// 思路:最后一个元素代替堆顶元素,删除最后一个元素,然后下窜
func (h *Heap02) remove() int {last := h.Size - 1root := h.Array[0]h.Array[0] = h.Array[last]//arr[last] 不用管了,因为长度要减1,减1后,最后一个元素也不存在了h.siftDown(0)h.Size--return root
}func (h Heap02) siftDown(idx int) {half := h.Size >> 1root := h.Array[0]for idx < half {// idx:只有左节点,或者左右子节点都有pos := (idx << 1) + 1child := h.Array[pos]right := pos + 1if !h.Asc {if right < h.Size && h.Array[right] > h.Array[pos] {pos = rightchild = h.Array[right]}if root > child {break}} else {if right < h.Size && h.Array[right] < h.Array[pos] {pos = rightchild = h.Array[right]}if root < child {break}}h.Array[idx] = childidx = pos}h.Array[idx] = root
}func (h Heap02) get() int { //获取堆顶元素if h.Size == 0 {const INT_MAX = int(^uint(0) >> 1)return ^INT_MAX}return h.Array[0]
}// 删除堆顶的元素的同时,插入一个新元素
func (h Heap02) replace(ele int) int { //替换堆顶元素const INT_MAX = int(^uint(0) >> 1)root := ^INT_MAXif h.Size == 0 {h.Array[0] = eleh.Size++} else {root = h.Array[0]h.Array[0] = eleh.siftDown(0)}return root
}
参考答案PHP
<?php/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** * @param index int整型 * @return int整型*/
function GetUglyNumber_Solution( $index )
{if($index ==0) return 0;//PHP中的优先级队列,或者叫堆,需要自己实现$h = new Heap();for($i=1;$i<=0x7fffffff;$i*=2){for($j=$i;$j<=0x7fffffff;$j*=3){for($k=$j;$k<0x7fffffff;$k*=5){$h->add($k);}}}while ($index>1) { //保留一个$h->remove();$index--;}return $h->remove();
}class Heap //堆
{public $arr = array();public $size = 0;public $defaultSize = 10;public $asc = true; //true: 小顶堆 false:大顶堆public function __construct(){for ($i = 0; $i < $this->defaultSize; $i++) {$this->arr[$i] = 0;}}public function ensureSize($len) //扩容代码{$oldSize = count($this->arr);if ($oldSize >= $len) return;$newSize = $oldSize + $oldSize >> 1;$arr1 = array();for ($i = 0; $i < $newSize; $i++) {$arr1[$i] = 0;if ($i < $oldSize) {$arr1[$i] = $this->arr[$i];}}$this->arr = $arr1;}public function add($val){$oldSize = $this->size;$this->ensureSize($oldSize + 1);$this->arr[$oldSize] = $val;$this->size++;$this->siftUp($oldSize);}public function siftUp($idx){ //上滤$root = $this->arr[$idx];while ($idx > 0) {$pindex = ($idx - 1) / 2;$parent = $this->arr[$pindex];if (!$this->asc) {if ($parent >= $root) break;} else {if ($parent <= $root) break;}$this->arr[$idx] = $parent;$idx = $pindex;}$this->arr[$idx] = $root;}//删除:二叉堆的删除是删除堆顶元素//思路:最后一个元素代替堆顶元素,删除最后一个元素,然后下窜public function remove(){$root = $this->arr[0];$this->arr[0] = $this->arr[$this->size - 1];//arr[last] 不用管了,因为长度要减1,减1后,最后一个元素也不存在了$this->siftDown(0);$this->size--;return $root;}public function siftDown($idx){$half = $this->size >> 1;$root = $this->arr[0];while ($idx < $half) {//index:只有左子节点,或者左右子节点都有$childIndex = ($idx << 1) + 1;$right = $childIndex + 1;$child = $this->arr[$childIndex];if (!$this->asc) {if ($right < $this->size && $this->arr[$right] > $this->arr[$childIndex]) {$childIndex = $right;$child = $this->arr[$right];}if ($child < $root) break;} else {if ($right < $this->size && $this->arr[$right] < $this->arr[$childIndex]) {$childIndex = $right;$child = $this->arr[$right];}if ($child > $root) break;}$this->arr[$idx] = $child;$idx = $childIndex;}$this->arr[$idx] = $root;}//获取堆顶元素public function get(){if ($this->size == 0) return 2147483647;return $this->arr[0];}//替换堆顶元素//删除堆顶的元素的同时,插入一个新元素public function replace($ele){$root = 2147483647;if ($this->size == 0) {$this->arr[0] = $ele;$this->size++;} else {$root = $this->arr[0];$this->arr[0] = $ele;$this->siftDown(0);}return $root;}
}