39.Ugly Number II(动态规划)
2015-10-23 12:27
197 查看
Write a program to find the
Ugly numbers are positive numbers whose prime factors only include
Note that
分析:找出第n个丑数。
方法一:
用三个l2,l3,l5的头节点分别表示该乘2,3,5的丑数。然后比较这三个值的大小,取最小的那个,然后把新的丑数分别加入到三个链表的尾部。最后返回尾节点的值。
即知道了第n-1个丑数,则第n个丑数是min(l2*2,l3*3,l5*5)中的那个。
方法二:可以对方法一进行简单的改进。把维护三个链表修改为维护一个链表,只不过是让l2,l3,l5分别表示对应下一个该乘2,3,5的节点。
方法三:用数组代替上述链表方法存储丑数。
后一个丑数肯定是在之前的丑数基础上乘以2或3或5得到的。
因此可以用数组保存已经求得的丑数,l2保存下一个该比较的乘2的结点的下标,l3保存下一个该比较的乘3的结点的下标,l5保存下一个该比较的乘5的结点的下标。
总结:清晰的思路,即使遇到看上去不会的题目,也不能太着急。慢慢来分析,总会找得到答案,加油@@@
n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include
2, 3, 5. For example,
1, 2, 3, 4, 5, 6, 8, 9, 10, 12is the sequence of the first
10ugly numbers.
Note that
1is typically treated as an ugly number.
分析:找出第n个丑数。
方法一:
用三个l2,l3,l5的头节点分别表示该乘2,3,5的丑数。然后比较这三个值的大小,取最小的那个,然后把新的丑数分别加入到三个链表的尾部。最后返回尾节点的值。
即知道了第n-1个丑数,则第n个丑数是min(l2*2,l3*3,l5*5)中的那个。
int getMin(int a,int b,int c){ if(a<b){ if(a<c){ return a; }else{ return c; } }else{ if(b<c){ return b; }else{ return c; } } } /*找出第n个丑数*/ public int nthUglyNumber(int n) { if(n == 1){ return 1; } ListNode l2 = new ListNode(1);//用三个节点保存一样的丑数序列,知道了第(n-1)个丑数,则第n个则是l2*2,l3*3,l5*5中最小的那个,然后该链表指向下一个。并且把新得到的那个加入到三个链表的最后 ListNode l3 = new ListNode(1); ListNode l5 = new ListNode(1); ListNode t2 = l2;//尾节点 ListNode t3 = l3; ListNode t5 = l5; for(int i = 2 ; i<=n; i++){ int a = l2.val * 2; int b = l3.val * 3; int c = l5.val * 5; int min = getMin(a,b,c); t2.next = new ListNode(min); t2 = t2.next; t3.next = new ListNode(min); t3 = t3.next; t5.next = new ListNode(min); t5 = t5.next; if(a == min){ l2 = l2.next; } if(b == min){ l3 = l3.next; } if(c == min){ l5 = l5.next; } } System.out.println(t2.val ); return t2.val; }
方法二:可以对方法一进行简单的改进。把维护三个链表修改为维护一个链表,只不过是让l2,l3,l5分别表示对应下一个该乘2,3,5的节点。
public int nthUglyNumber2(int n) { if(n == 1){ return 1; } //把方法一中的三个链表变成一个链表。 ListNode l2 = new ListNode(1);//表示下一个该比较的乘2节点 ListNode l3 = l2;//表示下一个该比较的乘3节点 ListNode l5 = l3;//表示下一个该比较的乘5节点 ListNode t2 = l2;//尾节点 for(int i = 2 ; i<=n; i++){ int a = l2.val * 2; int b = l3.val * 3; int c = l5.val * 5; int min = getMin(a,b,c); t2.next = new ListNode(min); t2 = t2.next; if(a == min){ l2 = l2.next; } if(b == min){ l3 = l3.next; } if(c == min){ l5 = l5.next; } } System.out.println(t2.val ); return t2.val; }
方法三:用数组代替上述链表方法存储丑数。
后一个丑数肯定是在之前的丑数基础上乘以2或3或5得到的。
因此可以用数组保存已经求得的丑数,l2保存下一个该比较的乘2的结点的下标,l3保存下一个该比较的乘3的结点的下标,l5保存下一个该比较的乘5的结点的下标。
public int nthUglyNumber3(int n) {//提交通过 if(n == 1){ return 1; } int[] nums = new int[n+1];//用数组存之前的丑数,其中nums[i]表示第i个丑数 nums[1]=1; int l2 = 1;//表示下一个该比较的乘2节点 int l3 = 1;//表示下一个该比较的乘3节点 int l5 = 1;//表示下一个该比较的乘5节点 for(int i = 2 ; i<=n; i++){ int a = nums[l2] * 2; int b = nums[l3] * 3; int c = nums[l5] * 5; int min = getMin(a,b,c); nums[i]=min; if(a == min){ l2++; } if(b == min){ l3++; } if(c == min){ l5++; } } return nums ; }
总结:清晰的思路,即使遇到看上去不会的题目,也不能太着急。慢慢来分析,总会找得到答案,加油@@@
相关文章推荐
- iOS开发~视频处理
- LITTLE SHOP OF FLOWERS
- 分区
- 大道至简第四章
- 关于Linux命令ls的一道笔试题
- 通过dumpsys meminfo命令查看一个进程的内存情况
- 关于rand和srand函数使用的一点心得
- VS2010 DSOFrame 编译遇到的问题总结
- 考虑overflow
- JDBC程序更新数据库中记录的方法
- MyEclipse10安装SVN插件
- 图片 动画
- 待补
- Visual Studio中11个强大的调试技巧和方法
- 使用copy con命令创建批处理文件
- C++——将成员函数作为参数
- BCompare文件对比软件使用总结
- android获取string.xml的值
- JAVA开发Web Service几种框架介绍
- 旋转字符串