LeetBook 谨记录个人的学习过程

LeetBook 算法题 题集,谨记录个人的学习过程

在本人学习的过程中 ,
遇到大量的 使用哨兵节点 俗称伪头 或者 伪尾。
,还有双指针 ,


简化新增删除操作 ,
ListNode newNode = new ListNode(0,head);

1.设计链表 (单向链表)

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

class MyLinkedList {
  int size;
  ListNode head;  
  public MyLinkedList() {
    size = 0;
    head = new ListNode(0);
  }

  public int get(int index) {
    if (index < 0 || index >= size) {
        return -1;
    }

    ListNode curr = head;
    for(int i = 0; i < index + 1; ++i) curr = curr.next;
    return curr.val;
  }

  public void addAtHead(int val) {
    addAtIndex(0, val);
  }

  public void addAtTail(int val) {
    addAtIndex(size, val);
  }

  public void addAtIndex(int index, int val) {
    if (index > size) {
         return;
    }

    if (index < 0) {
        return;
    }

    ++size;
    ListNode pred = head;
    for(int i = 0; i < index; ++i) {
        pred = pred.next;
    }

    ListNode toAdd = new ListNode(val);
    toAdd.next = pred.next;
    pred.next = toAdd;
  }

  public void deleteAtIndex(int index) {
    if (index < 0 || index >= size) {
        return;
    }

    size--;
    ListNode pred = head;
    for(int i = 0; i < index; ++i) {
        pred = pred.next;
    }

    pred.next = pred.next.next;
  }
}

环形链表 (给定一个链表,判断链表中是否有环。)

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head == null || head.next == null) {
            return false;
        }
        ListNode show = head;
        ListNode pNode = head.next;
        while (show != pNode) {
            if (pNode == null || pNode.next == null) {
                return false;
            }
            show = show.next;
            pNode = pNode.next.next;
        }
        return true;
    }
}

环形链表 (给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。)

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode pNode = head;
        Set<ListNode> seen = new HashSet<ListNode>();
        while (pNode != null) {
            if (seen.contains(pNode)) {
                return pNode;
            } else {
                seen.add(pNode);
            }
            pNode = pNode.next;
        }
        return null;
    }
}

相交链表 (找到两个单链表相交的起始节点。)

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode pNodeA = headA;
        ListNode pNodeB = headB;
        while (pNodeA != pNodeB) {
            pNodeA = (pNodeA == null) ? headB : pNodeA.next;
            pNodeB = (pNodeB == null) ? headA : pNodeB.next;
        }
        return pNodeA;
    }
}

删除链表的倒数第N个节点 (删除链表的倒数第 n 个节点,并且返回链表的头结点。)

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode first = head;
        ListNode newNode = new ListNode(0,head);    //哑节点 ,next指针域 指向链表的头节点 
        ListNode pNode = newNode;

        for (int i = 1; i <= n; ++i) {
            first = first.next;
        }
        while (first != null) {
            first = first.next;
            pNode = pNode.next;
        }
        pNode.next = pNode.next.next;
        return newNode.next;
    }
}

用于解决链表中双指针问题的模板

// Initialize slow & fast pointers
ListNode slow = head;
ListNode fast = head;
/**
 * Change this condition to fit specific problem.
 * Attention: remember to avoid null-pointer error
 **/
while (slow != null && fast != null && fast.next != null) {
    slow = slow.next;           // move slow pointer one step each time
    fast = fast.next.next;      // move fast pointer two steps each time
    if (slow == fast) {         // change this condition to fit specific problem
        return true;
    }
}
return false;   // change return value to fit specific problem

反转链表

1 > 3 > 2 > null --> 2 > 3 > 1 > null

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        ListNode pNode = head;
        while (pNode != null) {
            ListNode newNode = pNode.next;
            pNode.next = prev;
            prev = pNode;
            pNode = newNode;
        }
        return prev;
    }
}

移除链表元素 (删除链表中等于给定值 val 的所有节点。)

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode seen = new ListNode(0);
        seen.next = head;
        ListNode newNode = seen;
        ListNode pNode = head;
        while (pNode != null) {
            if (pNode.val == val) {
                newNode.next = pNode.next;
            } else {
                newNode = pNode;
            }
            pNode = pNode.next;
        }
        return seen.next;
    }
}

奇偶链表 (给定一个链表 ,按顺序将 奇数节点编号 和 偶数节点编号 放在一起)

1>2>4>5>8 -- > 1>4>8>2>5

class Solution {
    public ListNode oddEvenList(ListNode head) {
        if (head == null) {
            return head;
        }
        ListNode evevNode = head.next;
        ListNode newNode = head;
        ListNode pNode = evevNode;
        while (pNode != null && pNode.next != null) {
            newNode.next = pNode.next;
            newNode = newNode.next;
            pNode.next = newNode.next;
            pNode = pNode.next;
        }
        newNode.next = evevNode;
        return head;
    }
}

回文链表 (判断是否为回文链表)

1>2>2>1

class Solution {
    public boolean isPalindrome(ListNode head) {
        Stack<Integer> cruu = new Stack<>();
        ListNode pNode = head;
        while (pNode != null) {
            cruu.push(pNode.val);
            pNode = pNode.next;
        }
        while (head != null) {
            if (head.val != cruu.pop()) {
                return false;
            }
            head = head.next;
        }
        return cruu.isEmpty();
    }
}

合并两个有序链表

从小到大
1:1>2>3>4>5>null
2:2>3>5>7>null
变成 :1>2>2>3>3>4>5>5>7>null

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode newNode = new ListNode(-1);
        ListNode pNode = newNode;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                pNode.next = l1;
                l1 = l1.next;
            } else {
                pNode.next = l2;
                l2 = l2.next;
            }
            pNode = pNode.next;
        }
        // 有序的链表 ,最后只会剩一个没有连接  
        // pNode的下一个节点引用 指向  如果 l1 == null  就指向 l2 ,否则  指向 l1 .
        pNode.next = (l1 == null) ? l2 : l1;
        return newNode.next;
    }
}
posted @ 2020-12-02 20:03  san只松鼠  阅读(277)  评论(0)    收藏  举报