下面是做剑指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;
}