剑指offer-js编写-链表
下面是做剑指offer中,链表系列题的总结,参考答案如下:
(1)输入一个链表,从尾到头打印链表每个节点的值。
思路:用一个数组来接收打印的链表,链表的结构已经给出。
/*function ListNode(x){
this.val = x;
this.next = null;
}*/
function printListFromTailToHead(head)
{
var arr=[];
while(head){
arr.unshift(head.val);
head=head.next;
}
return arr;
}
(2)
输入一个链表,输出该链表中倒数第k个结点。
function FindKthToTail(head, k)
{
var arr=[];
while(head)
{
arr.push(head);
head=head.next;
}
if(arr.length==0 || k>arr.length){return false;}
return arr[arr.length-k];
}
(3)输入一个链表,反转链表后,输出链表的所有元素。
思路:新建一个头结点,遍历原链表,把每个节点用头结点插入到新建链表中。最后,新建的链表就是反转后的链表。
function ReverseList(pHead)
{
var pre = null;
var next = null;
while(pHead){
next = pHead.next;
pHead.next = pre;
pre = pHead;
pHead = next;
}
return pre;
}
(4)输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
function Merge(pHead1, pHead2)
{
if (pHead1 == null || pHead2 == null) {
return pHead1 || pHead2;
}
var head = null;
if (pHead1.val < pHead2.val) {
head = pHead1;
head.next = Merge(pHead2,pHead1.next)
}
else {
head = pHead2;
head.next = Merge(pHead1, pHead2.next);
}
return head;
}
(5)输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。
递归思想:把大问题转化若干子问题此题转化为一个头结点和除去头结点剩余部分,剩余部分操作和原问题一致
function RandomListNode(x){
this.label = x;
this.next = null;
this.random = null;
}
function Clone(pHead)
{
if(!pHead){
return null;
}
var CloneHead=new RandomListNode(pHead.label);
CloneHead.label=pHead.label;
CloneHead.random=pHead.random;
CloneHead.next=Clone(pHead.next);
return CloneHead;
}
(6)输入两个链表,找出它们的第一个公共结点。
思路:用两个指针扫描”两个链表“,最终两个指针到达 null 或者到达公共结点。
/*function ListNode(x){ this.val = x; this.next = null;}*/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;}/*function ListNode(x){ this.val = x; this.next = null;}*/function deleteDuplication(pHead){ if(pHead == null){ return null; } if(pHead!=null&&pHead.next == null){
return pHead; } var cur; if(pHead.next.val == pHead.val){ //对重复结点的处理
cur = pHead.next.next; while(cur!=null&&cur.val == pHead.val){ //遍历到没有重复结点的位置
cur = cur.next; } return deleteDuplication(cur); }else{ cur = pHead.next; //该结点不重复,递归下一个结点
pHead.next = deleteDuplication(cur); return pHead; }}(8)一个链表中包含环,请找出该链表的环的入口结点。
/*function ListNode(x){ this.val = x; this.next = null;}*/function EntryNodeOfLoop(pHead){ //首先判断链表中是否有环,并且返回环的长度 var p1 = pHead; var p2 = pHead.next; var count = 1; while(p1!=p2){ if(p1&&p2&&p1.next&&p2.next){ p1 = p1.next; p2 = p2.next.next; }else{ return null; } } //统计环的个数 p2 = p2.next; while(p1!=p2){ count++; p2 = p2.next; } //寻找环的入口 p1=pHead; p2=pHead; for(var i=0; i<count; i++){ p2 = p2.next; } while(p1!=p2){ p1=p1.next; p2=p2.next; } return p1;}

浙公网安备 33010602011771号