常见算法学习笔记
2012-04-11 15:50
423 查看
1)、求单向链表倒数第k个元素
思想:通过双指针实现,设指针p、q初试都指向头结点。指针p后移k次,然后指针p、q一起后移直到p指向空指针。写代码过程中要考虑一些异常情况,如K大于链表长度等。实现代码如下:
#include<iostream> using std::cin; using std::cout; using std::endl; using std::runtime_error; struct ListNode { int num; ListNode *next; }; int getLastKNum(ListNode *head,int k) { if(head==NULL) { throw runtime_error("头指针为空"); } if(k<=0) throw runtime_error("k必须为正数"); ListNode *p=head,*q=head; while(k>0&&p)//p右移k次 { p=p->next; --k; } if(k>0) throw runtime_error("K大于链表长度!"); while(p) { p=p->next; q=q->next; } if(q==head)//当k等于链表长度+1. throw runtime_error("K大于链表长度!"); else return q->num; } void deleteList(ListNode *head)//释放空间 { ListNode *p=head; ListNode *q=head; while(p) { q=p; p=p->next; delete q; } } int main() { ListNode *head=new ListNode(); head->next=NULL; for(int i=1;i<10;i++) { ListNode *tmp=new ListNode(); tmp->num=i; tmp->next=head->next; head->next=tmp; } try { for(int i=1;i<=9;i++) cout<<getLastKNum(head,i)<<endl; }catch(runtime_error err) { cout<<err.what()<<endl; } deleteList(head); }
2)求500万以内的亲和数
思想来自于July博客http://blog.csdn.net/v_july_v/article/details/6441279。2.1、什么是亲和数?
以下是摘自维基百科的解释:
相亲数(Amicable Pair),又称亲和数、友爱数,指两个正整数中,彼此的全部约数之和(本身除外)与另一方相等。
例如220与284:
220的全部约数(除掉本身)相加是:1+2+4+5+10+11+20+22+44+55+110=284
284的全部约数(除掉284本身)相加的和是:1+2+4+71+142=220
换句话说,亲和数又可以说成是两个正整数中,一方的全部约数之和与另一方的全部约数之和相等。
220的全部约数之和是:1+2+4+5+10+11+20+22+44+55+110+220 = 284+220 = 504
284的全部约数之和是:1+2+4+71+142+284 = 220+284 = 504
2.2、问题的难点:
因为基数比较大,如何能够快速的查找出亲和数这是一个难点.方法是以空间换时间.申请可以存放500万个整数的数组Divisor,数组存放每个数的亲和数.数n=Divisor[Divisor
]即为一对亲和数.
如何求全部约数之和:
1.简单办法:
int SumOfDivisor(int n) { int sum=1; for(int i=2;i<=n/2;i++) { if(n%i==0) sum+=i; } }而July采用了另一个种办法.
比如说2这个数字,它一定是4,6,8...的约数.即2i的约数都会有2.可以依次将该数添加到Divisor数组中.其实这两种方式求约数之和是差不多的.但为什么我这里需要特别指出.主要是上周六参加腾讯实习生笔试,第一道附加题就需要用这种思想.哎,当时没想起,吃亏啊...
代码如下:
#include<iostream> using std::cin; using std::cout; using std::endl; void Amicable_Pair(int n); int main() { int n; cin>>n; Amicable_Pair(n); return 0; } /* *求n内的亲和数 */ void Amicable_Pair(int n) { int *num=new int ; for(int i=0;i<n;i++) num[i]=1; for(int i=2;i<=n/2;i++) { int j=i+i; while(j<n) { num[j]+=i; j+=i; } }//求出1-n的所有约数(除去本身) for(int i=220;i<n;i++) { if(i<num[i]&&num[i]<n&&i==num[num[i]]) cout<<i<<" "<<num[i]<<endl; } delete[] num; }
3、求平方根算法实现
相关文章推荐
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- Hadoop学习笔记—12.MapReduce中的常见算法
- Hadoop学习笔记—12.MapReduce中的常见算法
- 数据结构学习笔记 --- 线性表 (一些常见的关于链表的算法和面试题)
- Hadoop学习笔记—12.MapReduce中的常见算法
- Hadoop学习笔记—12.MapReduce中的常见算法
- 算法学习笔记:爬山法与模拟退火
- 大数据算法学习笔记(3):亚线性算法概述
- 黑马程序员—Java基础学习笔记之排序算法:选择排序&冒泡排序
- 【iOS学习笔记】iOS算法(一)快速排序算法
- 【算法】数据结构与算法分析学习笔记——第四章AVL树C语言实现
- Struts2.0学习笔记---ognl表达式的常见用法
- C++精华(STL)学习笔记之算法
- 机器学习笔记4——生成学习算法
- 算法学习笔记----二叉搜索树
- 感知机算法及应用学习笔记
- 韩顺平_PHP程序员玩转算法公开课(第一季)09_使用栈完成高级计算器(1)_学习笔记_源代码图解_PPT文档整理
- 【算法学习笔记】11.数据结构基础 二叉树初步练习4
- 【算法学习笔记】之分治算法
- |算法讨论|RMQ 学习笔记