面试手撕代码总结(二)-链表篇

面试手撕代码总结(二)-链表篇

1.合并两个有序链表

 public ListNode Merge(ListNode list1,ListNode list2) {
	        if(list1==null){
	            return list2;
	        }
	         if(list2==null){
	            return list1;
	        }
	        ListNode newhead =null;
	        if(list1.val<=list2.val){
	           newhead = list1;
	            newhead.next=Merge(list1.next,list2);
	        }else{
	            newhead = list2;
	            newhead.next=Merge(list1,list2.next);
	        }
	        return newhead;
	}

2.删除链表中重复的节点

 public ListNode deleteDuplication(ListNode pHead) {
         if (pHead == null) {
            return null;
        }
        ListNode head = new ListNode(0);
        ListNode pre = head;
        ListNode now = pHead;
        head.next = pHead;
        while (now != null && now.next != null) {
            if (now.val == now.next.val) {
                int val = now.val;
                while (now != null && now.val == val) {
                    now = now.next;
                }
                pre.next = now;
            } else {
                pre.next = now;
                pre = now;
                now = now.next;
            }
        }
        return head.next;
    }

3.打印两个链表的第一个公共节点

public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
       if (pHead1 == null||pHead2 == null) {
            return null;
        }
        int count1 = 0;
        ListNode p1 = pHead1;
        while (p1!=null){
            p1 = p1.next;
            count1++;
        }
        int count2 = 0;
        ListNode p2 = pHead2;
        while (p2!=null){
            p2 = p2.next;
            count2++;
        }
        int flag = count1 - count2;
        if (flag > 0){
            while (flag>0){
                pHead1 = pHead1.next;
                flag --;
            }
        while (pHead1!=pHead2){
            pHead1 = pHead1.next;
            pHead2 = pHead2.next;
        }
        return pHead1;
    }
        if (flag <= 0){
            while (flag<0){
                pHead2 = pHead2.next;
                flag ++;
            }
            while (pHead1 != pHead2){
                pHead2 = pHead2.next;
                pHead1 = pHead1.next;
            }
            return pHead1;
        }
        return null;
    } 
}

4.链表奇数偶数节点

public ListNode oddEvenList(ListNode head) {
        if (head == null) return null;
        ListNode odd = head, even = head.next, evenHead = even;
        while (even != null && even.next != null) {
            odd.next = even.next;
            odd = odd.next;
            even.next = odd.next;
            even = even.next;
        }
        odd.next = evenHead;
        return head;
    }

5.链表的回文结构

class Solution {
    public boolean isPalindrome(ListNode head) {
       // 要实现 O(n) 的时间复杂度和 O(1) 的空间复杂度,需要翻转后半部分
        if (head == null || head.next == null) {
            return true;
        }
        ListNode fast = head;
        ListNode slow = head;
        // 根据快慢指针,找到链表的中点
        while(fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        slow = reverse(slow.next);
        while(slow != null) {
            if (head.val != slow.val) {
                return false;
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }

    private ListNode reverse(ListNode head){
        // 递归到最后一个节点,返回新的新的头结点
        if (head.next == null) {
            return head;
        }
        ListNode newHead = reverse(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}

6.复杂链表的复制

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;
    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        if(pHead==null){
            return null;
        }
      RandomListNode head=new RandomListNode(pHead.label);  
      RandomListNode temp=head;
      while(pHead.next!=null){
          temp.next=new RandomListNode(pHead.next.label);
          if(pHead.random!=null){
              temp.random=new RandomListNode(pHead.random.label);
          }
          pHead=pHead.next;
          temp=temp.next;
      }
        return head;
    }
}

7.检测链表是否有环

//(1)链表是否有环
 public boolean hasCycle(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        if(fast==null) return false;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(slow==fast){
                return true;
            }
        }
        return !(fast==null||fast.next==null);
    }
//(2)链表中环的入口节点
 public ListNode EntryNodeOfLoop(ListNode pHead){
        if(pHead==null||pHead.next==null)return null;
        ListNode p1=pHead;
        ListNode p2=pHead;
        while(p2!=null&&p2.next!=null){
            p1=p1.next;
            p2=p2.next.next;
            if(p1==p2){
              p1=pHead;
              while(p1!=p2){
                p1=p1.next;
                p2=p2.next;
              }
             if(p1==p2)return p1;
            }
        }
       return null;
    }

8.判断两个链表是否相交

public boolean isIntersect(Node h1,Node h2){
    if(h1==null||h2=null){
	   return false;
	   }
	Node tail1=h1;
	while(tail1.next!=null){
	   tail1=tail1.next;
	}
	Node tail2=h2;
	while(tail2.next!=null){
	   tail2=tail2.next;
	}
	return tail1==tail2;
}

9.两数相加链表

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode p = l1, q = l2, curr = dummyHead;
    int carry = 0;
    while (p != null || q != null) {
        int x = (p != null) ? p.val : 0;
        int y = (q != null) ? q.val : 0;
        int sum = carry + x + y;
        carry = sum / 10;//去掉最后一位,进位
        curr.next = new ListNode(sum % 10);
        curr = curr.next;
        if (p != null) p = p.next;
        if (q != null) q = q.next;
    }
    if (carry > 0) {
        curr.next = new ListNode(carry);
    }
    return dummyHead.next;
}

10.翻转链表

  public ListNode ReverseList(ListNode head) {
        if(head ==null){
           return null;
        }
        ListNode temp = null;
        while(head!=null){
            ListNode p = head.next;
            head.next = temp;
            temp=head;
            head=p;
        }
        return temp;
    }

你可能感兴趣的:(java核心技术,手撕代码-链表)