一,Leedcode面试题0205链表求和

 //方法2:递归

   public static ListNode addTwoNumbers(ListNode l1, ListNode l2) {

       //递归终止条件

       if (l2 == null){

           return l1;

       }

       if (l1 == null){

           return l2;

       }

       ListNode h1 = l1;

       ListNode h2 = l2;

       //我只知道当前两个链表d额头节点的和,剩下的我不知道,交给add方法

       //如果有节点为空,并且temp== 0,直接返回还有节点的链表

       int temp = (h1.val + h2.val ) > 9 ? 1 : 0;

       if (temp == 0){

           h1.val = (h1.val + h2.val );

       }else {//temp = 1;

           h1.val = ((h1.val + h2.val) % 10);

           h1.next = addIsOverTen(h1.next,temp);

       }

       h1.next = addTwoNumbers(h1.next,h2.next);

       return h1;

   }

   //方法1:开辟新空间

   public static ListNode addTwoNumbers1(ListNode l1, ListNode l2) {

       //方法1:创建一个新链表

       ListNode dummy = new ListNode();

       ListNode dummyHead = dummy;

       if (l1 == null){

           return l2;

       }

       if (l2 == null){

           return l1;

       }

       ListNode h1 = l1;

       ListNode h2 = l2;

       int temp = 0;

       while (h1 != null && h2 != null){

           int sum = h1.val + h2.val + temp;

           if (sum > 9){

               temp = 1;

           }else {

               temp = 0;

           }

           dummy.next = new ListNode(sum % 10);

           h1 = h1.next;

           h2 = h2.next;

           dummy = dummy.next;

       }

       //如果有节点为空,并且temp== 0,直接返回还有节点的链表

       if (temp == 0){

           dummy.next = h1 == null ? h2 : h1;

       }else {//temp = 1;

           //判断那个节点为空

           if (h1 == null && h2 == null){

               dummy.next = new ListNode(1);

           }else if (h1 == null){

               dummy.next = addIsOverTen(h2,temp);

           }else {

               dummy.next = addIsOverTen(h1,temp);

           }

       }

       return dummyHead.next;

   }

   public static ListNode addIsOverTen(ListNode head,int temp){

       if (head == null){

           return new ListNode(temp);

       }

       ListNode cur = head;

       if ((cur.val + temp) > 9){

           cur.val = 0;

           temp = 1;

           if (cur.next == null){

               cur.next = new ListNode(1);

           }else {

               addIsOverTen(cur.next,temp);

           }

       }else {

           cur.val += 1;

       }

       return head;

   }

二,Leedcode19删除链表的倒数第N个结点

public ListNode removeNthFromEnd(ListNode head, int n) {

       int len = 1;

       ListNode node = head;

       int count = 1;

       while(node.next != null){

           len++;

           node = node.next;

       }

       node = head;

       if(len == n){

           head = head.next;

           return head;

       }

       while(count < len-n){

           node = node.next;

           count++;

       }

       node.next = node.next.next;

       return head;

   }


三,Leedcode21合并两个有序链表

//方法1

   public ListNode mergeTwoLists1(ListNode list1, ListNode list2) {

       //虚拟头节点

       ListNode head = new ListNode();

       ListNode cur = head;

       while (list1 != null && list2 != null){

           if (list1.val <= list2.val){

               cur.next = list1;

               cur = list1;

               list1 = list1.next;

           }else {

               cur.next = list2;

               cur = list2;

               list2 = list2.next;

           }

       }

       if (list1 == null){

           cur.next = list2;

       }

       if (list2 == null){

           cur.next = list1;

       }

       return head.next;

   }

   //方法2:递归

   /**

    * 传入两个链表list1和list2就能拼接成一个有序的单链表,返回头节点

    * @param list1

    * @param list2

    * @return

    */

   public ListNode mergeTwoLists(ListNode list1, ListNode list2) {

       //递归结束条件

       if (list1 == null){

           return list2;

       }

       if (list2 == null){

           return list1;

       }

       if (list1.val <= list2.val){

           list1.next = mergeTwoLists(list1.next,list2);

           return list1;

       }else {

           list2.next = mergeTwoLists(list1,list2.next);

           return list2;

       }

   }


四,Leedcode82删除排序链表中的重复元素

//三指针法

   public static ListNode deleteDuplicates1(ListNode head) {

       //创建一个虚拟节点,防止头节点就是重复的节点,而导致头节点无法删除

       ListNode dummyHead = new ListNode();

       //创建一个prev节点用来遍历虚拟节点绑定的链表

       ListNode prev = dummyHead;

       //让虚拟节点的next指向链表的头节点

       dummyHead.next = head;

       //创建一个新的节点,用来指向虚拟节点的下一个节点

       ListNode cur = prev.next;

       //如果cur不为空,说明链表至少存在一个节点

       while (cur != null){

           //创建一个新的节点next,初识默认指向cur的next,next的作用是来用来判断cur和next是否为重复节点

           ListNode next = cur.next;

           //next=null,说明此时已经将整个链表遍历结束(链表只有一个元素),此时返回dummyHead.next;

           if (next == null){

               return dummyHead.next;

           }

           //走到这里说明此时链表的遍历没有到最后

           //如果cur和next节点的值相等,说明节点是重复的,此时所有需要删除节点,如果不相等,说明没有重复节点,三个指针同时向后移动,开始下一次while循环

           //如果不相等,执行if语句,说明此时节点不为重复节点

           if (cur.val != next.val){

               //将三个节点全部后移一位,这里只写prev后移和cur的后移,是应为next在进入while循环时,定义的就是cur的下一个节点,默认就相当于后移一位

               prev = prev.next;

               cur = cur.next;

           }else {

               //如果存在重复值,next一直后移,直到找到不重复的节点,找到next与cur不重复的节点以后,将prev.next = next;直接删除prev到next之间所有重复的节点

               //因为要执行next = next.next,所以在这里需要保证next不为空,否则会空指针异常

               while (next != null && cur.val == next.val){

                   next = next.next;

               }

               //走到这里说明此时next节点与cur不重复,让prev.next指向next,删除所有重复的节点,让cur=next,开始下一次循环时,cur = next ,next = cur.next;继续用来判断是否存在重复节点

               prev.next = next;

               cur = next;

           }

       }

       //走到这里说明此时已经遍历完成所有的节点,返回dummy.next;

       //因为dummyHead没有存储val,dummyhead.next指向head头节点,所以返回demmyHead.next;

       return dummyHead.next;

   }

   //递归解法

   /**

    * 方法语义:给你一个链表的头节点,你就可以删除链表中所有重复出现的所有节点

    * @param head

    * @return

    */

   //此方法不对,分析的思路不对

   public static ListNode deleteDuplicates2(ListNode head) {

       //1.终止条件

       //如果链表为空,或者链表中只有一个节点,肯定就不会存在重复节点

       if (head == null || head.next == null){

           return head;

       }

       //走到这里说明链表至少存在两个节点

       //需要创建一个虚拟节点用来删除头节点就是重复节点的情况

       ListNode dummyHead = new ListNode();

       dummyHead.next = head;

       //将头节点以后的节点传入具有删除重复节点的方法中,会返回一个新的节点

       ListNode newHead = deleteDuplicates(head.next);

       //判断newHead和head的是否重复

       if (head.val == newHead.val){

           //执行到此,说明节点head和剩余节点删除重复节点以后返回的新节点相等,说明head和newHead重复。

           //此时将dummyHead.next = newHead.next就会将head和newHead重复的节点全部删掉

           dummyHead.next = newHead.next;

       }else {

           //走到这里,说明head和newHead不重复,直接拼接

           head.next = newHead;

       }

       //拼接完成,返回dummyHead.next

       return dummyHead.next;

   }

   /**

    * 方法语义:给你一个链表的头节点,你就可以删除链表中所有重复出现的所有节点,返回一个新节点

    * @param head

    * @return

    */

   public static ListNode deleteDuplicates(ListNode head) {

       //终止条件

       if (head == null || head.next == null){

           return head;

       }

       //说明至少存在两个节点

       //判断两节点是否相等,如果不相等

       if (head.val != head.next.val){

           //如果不相等 ,  当前头节点直接拼接剩余节点删除重复节点的后返回的新节点头

           head.next = deleteDuplicates(head.next);

           return head;

       }else {

           //两节点重复

           ListNode node = head.next;

           while (node != null && node.val == head.val){

               node = node.next;

           }

           //如果重复,找到重复的节点以后,调用改方法,直接不和头节点拼接,直接返回,就会将重复的头节点一并删除掉

           return deleteDuplicates(node);

       }

   }