链表
1.从尾到头打印链表
要注意区分while和if的区别:
while是个循环,只有条件为假才跳出循环
if只判断一次。
2.链表中倒数第k个节点
一般链表的问题我们都用双指针来解决。这个题主要要考虑健壮性。首先我们要判断头节点不为空,k>0。
其次在运行的过程中也要一直保证节点不为空
思路:求倒数第k个节点,其实就是第n-k+1个节点,可以写为n-(k-1)个节点。定义两个指针,快指针先走k-1步,之后慢指针才开始走。当快指针走到末尾时,慢指针走到了倒数第k个节点。
代码如下:
/*function ListNode(x){ this.val = x; this.next = null; }*/ function FindKthToTail(head, k) { if(head==null||k<0){ return false; } var fast = head; var low = head; for(i=0;i<k;i++){ if(fast!=null){ fast = fast.next }else { return false; } } while(fast){ fast = fast.next; low = low.next; } return low; }
3.反转链表:输入一个链表,反转链表后,输出新链表的表头。
这里需要定义三个指针,分别指向结点的前一个结点,结点,结点的后一个节点。同时要注意判断鲁棒性。
(需要重做一遍,最后三个节点赋值那里一直不清楚)
4.合并两个排序的链表:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则
普通的递归。但是要注意链表为空的情况
function Merge(pHead1, pHead2) { if(pHead1==null){ return pHead2; } if(pHead2==null){ return pHead1; } var result = {}; if(pHead1.val<pHead2.val){ result = pHead1; result.next = Merge(pHead1.next,pHead2) }else{ result = pHead2; result.next = Merge(pHead2.next,pHead1) } return result; }
5.复杂链表的赋值
这个对我来说完全没有理解,打算先把其他的链表做了。
6.两个链表的公共结点
function FindFirstCommonNode(pHead1, pHead2) { var p1 = pHead1; var p2 = pHead2; while(p1!=p2){ p1= (p1==null)?pHead2:p1.next p2= (p2==null)?pHead1:p2.next } return p1; }
7.链表中环的入口结点
思路:定义两个节点,快结点一次走两步,慢节点一次走一步。如果两者相遇就说明有环,且两指针相遇的地方一定在环中,这时候再从该节点出发并且此时定义一个节点,这个节点初始值为头节点,头节点和慢节点相遇的位置一定是入口结点。
错误原因:每次用while的位置总是错用成if
是否重做:是
function EntryNodeOfLoop(pHead) { var fast = pHead; var slow = pHead; while(fast!==null&&fast.next!==null){ fast= fast.next.next; slow = slow.next if(fast==slow){ var p = pHead; while(p!=slow){ p=p.next; slow = slow.next; } return p; } } return null; }