2.2 题目:
找出单向链表中倒数第k个结点
解法:
递归版:
构造一个int包装类,实现参数传递,都指向同一个int,而不是值传递时复制一份
- public static class IntWrapper{
- public int value = 0;
- }
- public static <E> Node<E> nthToLast(Node<E> head, int k, IntWrapper i){
- if(head == null)
- return null;
- Node<E> node = nthToLast(head.next,k,i);
- i.value = i.value + 1;
- if(i.value == k)
- return head;
- return node;
- }
迭代版:
两个指针p1 p2 p1指向头,p2指向第k个结点,之后p1 p2 同速向后遍历,p2遍历到结尾时,p1指向的就是倒数第k个结点
- public static <E> Node<E> nthToLast(Node<E> head,int k){
- Node<E> p1 = head;
- Node<E> p2 = head;
- for(int i=0;i < k-1 ;i++){
- if(p2 == null) return null;
- p2 = p2.next;
- }
- while(p2.next != null){
- p1 = p1.next;
- p2 = p2.next;
- }
- return p1;
- }
测试用例:
- @Test
- public void test_2_2(){
- Node<Integer> head = new Node<Integer>(0);
- head = createIntegerNode(head,1000);
- long start = System.currentTimeMillis();
- Node<Integer> node = LinkedListUtil.nthToLast(head, 1000);
- long end = System.currentTimeMillis();
- System.out.println("time is " + (end - start));
- System.out.println(node.toString());
- long start2 = System.currentTimeMillis();
- Node<Integer> node1 = LinkedListUtil.nthToLast(head, 1000,new IntWrapper());
- long end2 = System.currentTimeMillis();
- System.out.println("time is " + (end2 - start2));
- System.out.println(node1.toString());
- }
- private Node<Integer> createIntegerNode(Node<Integer> head,int number){
- Node<Integer> p = head;
- for(int i = 1;i < number;i++){
- if(i<(number/2)){
- p.setNext(new Node<Integer>(i));
- }
- else{
- p.setNext(new Node<Integer>(i%(number/2)));
- }
- p = p.getNext();
- }
- return head;
- }
建议:尽量不要使用递归,很容易导致栈溢出。