法中执行次数最多的那条语句是基本语句Q通常是最内层循环的@环体?/p>
?计算基本语句的执行次数的数量U;
只需计算基本语句执行ơ数的数量Q这意味着只要保证基本语句执行ơ数的函C的最高次q正即可,可以忽略所有低ơ幂和最高次q的pL。这栯够简化算法分析,q且使注意力集中在最重要的一点上Q增长率?/p>
?用大Ο记号表示法的时间性能?/p>
基本语句执行次数的数量U放入大Ο记号中?/p>
如果法中包含嵌套的循环Q则基本语句通常是最内层的@环体Q如果算法中包含q列的@环,则将q列循环的时间复杂度相加。例如:
for (i=1; i<=n; i++)
x++;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
x++;
W一个for循环的时间复杂度?#927;(n)Q第二个for循环的时间复杂度?#927;(n2)Q则整个法的时间复杂度?#927;(n+n2)=Ο(n2)?/p>
常见的算法时间复杂度由小到大依次为:
Ο(1)Q?#927;(log2n)Q?#927;(n)Q?#927;(nlog2n)Q?#927;(n2)Q?#927;(n3)Q?#8230;Q?#927;(2n)Q?#927;(n!)
Ο(1)表示基本语句的执行次数是一个常敎ͼ一般来_只要法中不存在循环语句Q其旉复杂度就?#927;(1)?#927;(log2n)?#927;(n)?#927;(nlog2n)?#927;(n2)?#927;(n3)UCؓ(f)多项式时_?#927;(2n)?#927;(n!)UCؓ(f)指数旉。计机U学家普遍认为前者是有效法Q把q类问题UCؓ(f)Pc问题,而把后者称为NP问题?/p>
O(1)
Temp=i;i=j;j=temp;
以上三条单个语句的频度均?Q该E序D늚执行旉是一个与问题规模n无关的常数。算法的旉复杂度ؓ(f)常数ӞCT(n)=O(1)。如果算法的执行?间不随着问题规模n的增加而增长,即ɽ法中有上千条语句,其执行时间也不过是一个较大的常数。此cȝ法的旉复杂度是O(1)?
O(n^2)
2.1. 交换i和j的内?br />
sum=0Q?nbsp; Q一ơ)
for(i=1;i<=n;i++) Qn?Q?br />
for(j=1;j<=n;j++) Qn^2?Q?br />
sum++Q?nbsp; Qn^2?Q?br />
解:T(n)=2n^2+n+1 =O(n^2)
2.2.
for (i=1;i<n;i++)
{
y=y+1; ?nbsp;
for (j=0;j<=(2*n);j++)
x++; ?nbsp;
}
解: 语句1的频度是n-1
语句2的频度是(n-1)*(2n+1)=2n^2-n-1
f(n)=2n^2-n-1+(n-1)=2n^2-2
该程序的旉复杂度T(n)=O(n^2).
O(n)
2.3.
a=0;
b=1; ?br />
for (i=1;i<=n;i++) ?br />
{
s=a+b; ?br />
b=a; ?nbsp;
a=s; ?br />
}
解: 语句1的频度:2,
语句2的频度: n,
语句3的频度: n-1,
语句4的频度:n-1,
语句5的频度:n-1,
T(n)=2+n+3(n-1)=4n-1=O(n).
O(logn )
2.4.
i=1; ?br />
while (i<=n)
i=i*2; ?br />
解: 语句1的频度是1,
设语?的频度是f(n), 则:2^f(n)<=n;f(n)<=logn
取最大值f(n)= logn,
T(n)=O(logn )
O(n^3)
2.5.
for(i=0;i<n;i++)
{
for(j=0;j<i;j++)
{
for(k=0;k<j;k++)
x=x+2;
}
}
解:当i=m, j=k的时?内层循环的次Cؓ(f)k当i=m? j 可以?0,1,...,m-1 , 所以这里最内@环共q行?+1+...+m-1=(m-1)m/2ơ所?i?取到n, 则@环共q行? 0+(1-1)*1/2+...+(n-1)n/2=n(n+1)(n-1)/6所以时间复杂度为O(n^3).
问题Q?/p>
1、如何判断一个链表是不是q类链表Q?br /> 2、如果链表ؓ(f)存在环,如果扑ֈ环的入口点?
解答Q?/p>
一、判断链表是否存在环Q办法ؓ(f)Q?/p>
讄两个指针(fast, slow)Q初始值都指向_slow每次前进一步,fast每次前进二步Q如果链表存在环Q则fast必定先进入环Q而slow后进入环Q两个指针必定相遇?当然Qfast先行头到N为NULLQ则为无环链?E序如下Q?/p>
bool IsExitsLoop(slist * head)
{
slist * slow = head , * fast = head;
while ( fast && fast -> next )
{
slow = slow -> next;
fast = fast -> next -> next;
if ( slow == fast ) break ;
}
return ! (fast == NULL || fast -> next == NULL);
}
二、找到环的入口点
当fast若与slow盔RӞslow肯定没有走遍历完链表Q而fast已经在环内@环了n?1<=n)。假设slowCs步,则fastC2s步(fast步数q等于s 加上在环上多转的n圈)Q设环长为rQ则Q?/p>
2s = s + nr
s= nr
设整个链表长LQ入口环与相遇点距离为xQv点到环入口点的距Mؓ(f)a?br />
a + x = nr
a + x = (n – 1)r +r = (n-1)r + L - a
a = (n-1)r + (L – a – x)
(L – a – x)为相遇点到环入口点的距离Q由此可知,从链表头到环入口点等?n-1)循环内环+盔R点到环入口点Q于是我们从链表头、与盔R点分别设一个指针,每次各走一步,两个指针必定盔RQ且盔RW一点ؓ(f)环入口点?/p>
E序描述如下Q?/p>
slist * FindLoopPort(slist * head)
{
slist * slow = head, * fast = head;
while ( fast && fast -> next )
{
slow = slow -> next;
fast = fast -> next -> next;
if ( slow == fast ) break ;
}
if (fast == NULL || fast -> next == NULL)
return NULL;
slow = head;
while (slow != fast)
{
slow = slow -> next;
fast = fast -> next;
}
return slow;
}
附一U易于理解的解释Q?/p>
一UOQnQ的办法是Q搞两个指针Q一个每ơ递增一步,一个每ơ递增两步Q如果有环的话两者必焉合,反之亦然Q:
关于q个解法最形象的比d是在操场当中跑步Q速度快的会把速度慢的扣圈
可以证明Qp2q赶上p1的时候,p1一定还没有走完一遍环路,p2也不会跨p1多圈才追?/p>
我们可以从p2和p1的位|差距来证明Qp2一定会赶上p1但是不会跌p1?/p>
因ؓ(f)p2每次?步,而p1C步,所以他们之间的差距是一步一步的~小Q?Q?Q?Q?Q? ?的时候就重合?/p>
Ҏ(gu)q个方式Q可以证明,p2每次C步以上,q不总能加快的速度Q反而有可能判别不出有环
既然能够判断出是否是有环路,那改如何扑ֈq个环\的入口呢Q?
解法如下Q?当p2按照每次2步,p1每次一步的方式赎ͼ发现p2和p1重合Q确定了单向链表有环路了
接下来,让p2回到链表的头部,重新赎ͼ每次步长不是?了,而是?Q那么当p1和p2再次盔R的时候,是环\的入口了?/p>
q点可以证明的:
在p2和p1W一ơ相遇的时候,假定p1Cn步骤Q环路的入口是在p步的时候经q的Q那么有
p1走的路径Q?p+c Q?nQ?nbsp; c为p1和p2怺点,距离环\入口的距?/p>
p2走的路径Q?p+c+k*L = 2*nQ?nbsp; L为环路的周长Qk是整?/p>
昄Q如果从p+c点开始,p1再走n步骤的话Q还可以回到p+cq个?/p>
同时p2从头开始走的话Q经qn步,也会辑ֈp+cq点
昄在这个步骤当中p1和p2只有前p步骤走的路径不同Q所以当p1和p2再次重合的时候,必然是在链表的环路入口点上?/p>
扩展问题Q?/p>
判断两个单链表是否相交,如果怺Q给出相交的W一个点Q两个链表都不存在环Q?/p>
比较好的Ҏ(gu)有两个:
一、将其中一个链表首q,另外一个链表是否存在环Q如果存在,则两个链表相交,而检出来的依赖环入口即为相交的W一个点?/p>
二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点Q我们可以先遍历一个链表,直到NQ再遍历另外一个链表,如果也可以走到同L(fng)l尾点,则两个链表相交?/p>
q时我们C两个链表lengthQ再遍历一ơ,镉K表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进Q每ơ一步,盔R的第一点即Z个链表相交的W一个点?/p>
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/ssfp8762/archive/2009/07/08/4331419.aspx
“JDK1.5”Q开发代L(fng)虎)的一个重要主题就是通过新增一些特性来化开发,q些Ҏ(gu)包括泛型,for-else 循环Q自动装?拆包Q枚举,可变参数, 静态导入 。用这些特性有助于我们~写更加清晰Q精(zhn),安全的代码?br />
Collection<String> c = new ArrayList(); c.add(new Date()); |
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date) |
void processAll(Collection c){ for(Iterator i=c.iterator(); i.hasNext();){ MyClass myObject = (MyClass)i.next(); myObject.process(); } } |
void processAll(Collection<MyClass> c){ for (MyClass myObject :c) myObject.process(); } |
int a = 3; Collection c = new ArrayList(); c.add(a);//自动转换成Integer. Integer b = new Integer(2); c.add(b + 2); |
public enum Color { Red, White, Blue } |
for (Color c : Color.values()) System.out.println(c); |
util.write(obj1); util.write(obj1,obj2); util.write(obj1,obj2,obj3); … |
public void write(Object... objs) { for (Object obj: objs) System.out.println(obj); } |
import static java.lang.Math.*; ……. r = sin(PI * 2); //无需再写r = Math.sin(Math.PI); |