剑指offer3.4-代码的鲁棒性
Posted lyeeer
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer3.4-代码的鲁棒性相关的知识,希望对你有一定的参考价值。
题目
输入一个链表,输出该链表中倒数第k个结点。
思路
1.首先想到的是走到链表的尾端,再由尾端回溯k步。可是链表的节点定义看出这是单向链表,结点只有从前往后的指针,因此不能这样走。
2.只能从头节点开始遍历链表。那么我们可以先获取链表的结点数,就可以计算从前往后是需要走多少步了。但是这样需要遍历两次链表
3.为了实现只遍历一次链表,我们还是像之前翻转数组一样,设立两个指针。第一个指针从链表的头指针开始遍历向前走k-1,第二个指针始终指向头结点。当第一个指针指向k个结点的时候,两个指针同时向前遍历,这样确保两个指针距离为k。那么当第一个指针指向末尾结点时,第二个指针指向的就是倒数第k个结点。
4.并且需要注意潜在崩溃的风险。当输入的head为空指针时,代码会试图访问空指针的内存空间;输入的链表结点数小于k,for循环中会在链表上向前走k-1步,同样会造成空指针;当k是unsigned int型时,输入的参数k为0,此时for循环的k得到的不是-1,而是0xFFFFFFFF(4294967295),执行次数会非常非常大,造成程序崩溃。
解法
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(head == null) return null; ListNode P1=head; while(P1!=null && k-->0) P1=P1.next; //如果k大于链表的长度 if(k>0){ return null; } ListNode P2=head; while(P1!=null){ P1=P1.next; P2=P2.next; } return P2; } }
题目
输入一个链表,反转链表后,输出新链表的表头。
思路
1.反转后链表的头结点就是原始链表的尾节点,即next为NULL的结点。
2.同样可以采用递归,使当前head的next指向null,不断反转。
3.或者采用头插法。构建一个新的指针用来指向
解法
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode ReverseList(ListNode head) { if(head == null || head.next == null) return head; ListNode next=head.next; head.next=null; ListNode newHead=ReverseList(next); next.next=head; return newHead; }
public
ListNode ReverseList(ListNode head) {
ListNode newList =
new
ListNode(-
1
);
while
(head !=
null
) {
ListNode next = head.next;
head.next = newList.next;
newList.next = head;
head = next;
}
return
newList.next;
}
}
题目
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路
1.链表的合并过程如下,从合并两个链表的头结点开始,当链表1的头结点的值小于链表2的头结点值,因此链表1的头结点将为合并后链表的头结点。剩余结点中,链表2的头结点值小于链表1的头结点的值,因此链表2的头结点是剩余结点的头结点,把这个结点和之前合并好的链表的尾节点链接起来。不断比较两个链表的头结点的值。
2.为了防止访问空指针指向的内存空间引起的崩溃,需要处理当两个链表为空链表时的结果,当都为空链表时,合并的结果就是空链表。
解法
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode Merge(ListNode list1,ListNode list2) { if(list1==null) return list2; if(list2==null) return list1; if(list1.val<=list2.val){ list1.next=Merge(list1.next,list2); return list1; } else{ list2.next=Merge(list1,list2.next); return list2; } } }
以上是关于剑指offer3.4-代码的鲁棒性的主要内容,如果未能解决你的问题,请参考以下文章