程序员面试金典--题目解析-2.2 找出单向链表中倒数第k个结点

2.2 题目:

找出单向链表中倒数第k个结点


解法:

递归版:

构造一个int包装类,实现参数传递,都指向同一个int,而不是值传递时复制一份

  1. public static class IntWrapper{  
  2.         public int value = 0;  
  3.     }  

  1. public static <E> Node<E> nthToLast(Node<E> head, int k, IntWrapper i){  
  2.         if(head == null)  
  3.             return null;  
  4.         Node<E> node = nthToLast(head.next,k,i);  
  5.         i.value = i.value + 1;  
  6.         if(i.value == k)  
  7.             return head;  
  8.         return node;  
  9.     }  


迭代版:

两个指针p1 p2 p1指向头,p2指向第k个结点,之后p1 p2 同速向后遍历,p2遍历到结尾时,p1指向的就是倒数第k个结点

  1. public static <E> Node<E> nthToLast(Node<E> head,int k){  
  2.         Node<E> p1 = head;  
  3.         Node<E> p2 = head;  
  4.           
  5.         for(int i=0;i < k-1 ;i++){  
  6.             if(p2 == nullreturn null;  
  7.             p2 = p2.next;  
  8.         }  
  9.           
  10.         while(p2.next != null){  
  11.             p1 = p1.next;  
  12.             p2 = p2.next;  
  13.         }  
  14.         return p1;  
  15.     }  

测试用例:

  1. @Test  
  2.     public void test_2_2(){  
  3.         Node<Integer> head = new Node<Integer>(0);  
  4.         head = createIntegerNode(head,1000);  
  5.         long start = System.currentTimeMillis();  
  6.         Node<Integer> node = LinkedListUtil.nthToLast(head, 1000);  
  7.         long end = System.currentTimeMillis();  
  8.         System.out.println("time is " + (end - start));  
  9.         System.out.println(node.toString());  
  10.           
  11.         long start2 = System.currentTimeMillis();  
  12.         Node<Integer> node1 = LinkedListUtil.nthToLast(head, 1000,new IntWrapper());  
  13.         long end2 = System.currentTimeMillis();  
  14.         System.out.println("time is " + (end2 - start2));  
  15.         System.out.println(node1.toString());  
  16.     }  
  17.       
  18.     private Node<Integer> createIntegerNode(Node<Integer> head,int number){  
  19.         Node<Integer> p = head;  
  20.         for(int i = 1;i < number;i++){  
  21.             if(i<(number/2)){  
  22.                 p.setNext(new Node<Integer>(i));  
  23.             }  
  24.             else{  
  25.                 p.setNext(new Node<Integer>(i%(number/2)));  
  26.             }  
  27.             p = p.getNext();  
  28.         }  
  29.         return head;  
  30.     }


建议:尽量不要使用递归,很容易导致栈溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值