链表相关操作

来源:互联网 发布:js二维数组排序函数 编辑:程序博客网 时间:2024/05/15 11:26

class ListNode{        int val;        ListNode next;        public ListNode(int val){            this.val=val;        }    }

1.链表反转,遍历原链表,采用头插法将数值插入新链表

public ListNode reverse(ListNode p){        if(p==null||p.next==null) return p;        ListNode cur = null;        while(p!=null){            ListNode tmp = p.next;            p.next = cur;            cur = p;            p = tmp;        }        return cur;    }
2.两个链表相加,如:1->2->3加4->5->6等于5->7->9。思路:短的链表高位用0补。

public class Solution {    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {        ListNode dummyHead = new ListNode(0);        if(l1 == null && l2 == null){            return dummyHead;        }        int sum = 0, carry = 0;        ListNode curr = dummyHead;        while(l1!=null || l2!=null){            int num1 = l1 == null? 0 : l1.val;            int num2 = l2 == null? 0 : l2.val;            sum = num1 + num2 + carry;            curr.next = new ListNode(sum % 10);            curr = curr.next;            carry = sum / 10;            l1 = l1 == null? null : l1.next;            l2 = l2 == null? null : l2.next;        }        if(carry!=0){            curr.next = new ListNode(carry);        }        return dummyHead.next;    }}
3.寻找单链表的环点,定义一个快速指针和慢速指针,当快速指针与慢速指针相遇时,链表存在环,当快速指针遇到NULL时,链表无环。

public boolean isExistLoop(ListNode p){        ListNode fast = p;        ListNode slow = p;        while(fast!=null&&fast.next!=null){            slow = slow.next;            fast = fast.next.next;            if(slow==fast) break;        }        return fast!=null&&fast.next!=null;    }
4.寻找单链表环点的位置,定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

public ListNode loopLocation(ListNode p){        ListNode fast = p;        ListNode slow = p;        while(fast!=null&&fast.next!=null){            slow = slow.next;            fast = fast.next.next;            if(slow==fast) break;        }        if(fast!=null&&fast.next!=null){            slow = p;            while(slow!=fast){                slow = slow.next;                fast = fast.next;            }            return slow;        }        return null;    }
5.环的长度,在碰撞点处,快指针与慢指针继续走,继续相遇的操作数即为换的长度。

6.链表的长度,换的长度加上头指针到环点位置的长度即为单链表的长度。

7.判断两个链表相交,如果两个链表相交,则他们最后一个元素一定相同。

public boolean isConNLoop(ListNode h1, ListNode h2) {      if (h1 == null || h2 == null)          return false;      ListNode n1 = h1;      ListNode n2 = h2;      while (n1.next != null)          n1 = n1.next;      while (n2.next != null)          n2 = n2.next;            if (n1 == n2)          return true;      return false;  } 

8.两个链表相交的位置:

public ListNode findPointNLoop(ListNode h1, ListNode h2) {      if (h1 == null || h2 == null)          return null;      ListNode n1 = h1;      ListNode n2 = h2;      int len1 = 0;      int len2 = 0;      while (n1 != null) {          n1 = n1.next;          len1++;      }      while (n2 != null) {          n2 = n2.next;          len2++;      }            n1 = h1;      n2 = h2;      if (len1 < len2) {          n1 = h2;          n2 = h1;      }                for (int i = len1-len2; i > 0; i--)          n1 = n1.next;            while (n1 != null && n1 != n2) {          n1 = n1.next;          n2 = n2.next;      }      return n1;        }  
9.

如果链表有环且相交,那么这两个链表都是有环的。

找到第一个链表的环点,然后将环断开(当然不要忘记了保存它的下一个节点),然后再来遍历第二个链表,如果发现第二个链表从有环变成了无环,那么他们就是相交的嘛,否则就是不相交的了。

public boolean isConLoop(ListNode h1, ListNode h2) {      ListNode temp = loopEntry(h1);      ListNode org = temp.next;      temp.next = null;      if (isLoop(h2)) {          temp.next = org;          return false;      } else {          temp.next = org;          return true;      }  }    public ListNode loopEntry(ListNode head) {      if (head == null)          return null;      ListNode slow = head;      ListNode fast = slow.next;      while (fast != null && fast.next != null && fast != slow) {          slow = slow.next;          fast = fast.next.next;      }      if (fast == slow) {          fast = head;          slow = slow.next;          while (fast != slow) {              slow = slow.next;              fast = fast.next;          }          return slow;      }      return null;  }  



0 0