数据结构之链表
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */
用虚节点放在head前面,可以让head的删除不必单独分析。
class Solution { public ListNode removeElements(ListNode head, int val) { ListNode virHead = new ListNode(); virHead.next = head; ListNode cur = virHead; while (cur.next != null) { if (cur.next.val == val) { cur.next = cur.next.next; } else { cur = cur.next; } } return virHead.next; } }
逆转除了双指针和递归,还可以用栈(单纯打印逆转数据)。
class Solution { public ListNode reverseList(ListNode head) { ListNode temp = new ListNode(); ListNode pre = null; ListNode cur = head; while(cur != null) { //结束时是cur为null,pre为原链表尾部 temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; } }
看作A和B都要走完两段路,如果有交点。因为总路程一样,相遇后的路程一样,所以相遇即相交。
如果A和B没有交点,即后来都到达了null。
public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { ListNode preA = headA; ListNode preB = headB; while (preA != preB) { preA = preA == null ? headB : preA.next; preB = preB == null ? headA : preB.next; } return preA; } }
迭代都会写,递归一看就会一写就废
class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (l1 == null) return l2; if (l2 == null) return l1; if (l1.val < l2.val) { l1.next = mergeTwoLists(l1.next, l2); return l1; } else { l2.next = mergeTwoLists(l1, l2.next); return l2; } } }
class Solution { public ListNode deleteDuplicates(ListNode head) { ListNode p = head; while(p != null && p.next != null) { if (p.val == p.next.val) { p.next = p.next.next; } else { p = p.next; } } return head; } }
快慢指针找位置,虚头节点删除。
class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode prehead = new ListNode(); prehead.next = head; ListNode r = prehead; ListNode l = prehead; for (int i = 0; i < n; i++) { r = r.next; } while (r != null && r.next != null) { r = r.next; l = l.next; } l.next = l.next.next; return prehead.next; } }
虽然我是一个只会用迭代的fw,但是我还是要把递归放上去。解析是递归(强烈建议看一看解析)。
class Solution { public ListNode swapPairs(ListNode head) { if (head == null || head.next == null) return head; ListNode newhead = head.next; head.next = swapPairs(newhead.next); newhead.next = head; return newhead; } }
class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { LinkedList<Integer> stack1 = new LinkedList<>(); LinkedList<Integer> stack2 = new LinkedList<>(); while (l1 != null) { stack1.addLast(l1.val); l1 = l1.next; } while (l2 != null) { stack2.addLast(l2.val); l2 = l2.next; } int count = 0; ListNode head = null; while (!stack1.isEmpty() || !stack2.isEmpty() || count != 0) { int n1 = !stack1.isEmpty() ? stack1.removeLast() : 0; int n2 = !stack2.isEmpty() ? stack2.removeLast() : 0; int val = (n1 + n2 + count) % 10; count = (n1 + n2 + count) / 10; ListNode temp = head; head = new ListNode(val); head.next = temp; } return head; } }
回文链表 题目
分隔链表 题目
奇偶链表 题目
一开始用奇链表当判断条件,结果还要分情况考虑。既然偶链表是加在后面的,循环时就根据偶链表来判断比较好哇。
class Solution { public ListNode oddEvenList(ListNode head) { if (head == null) return head; ListNode even = head.next; ListNode tempeven = even; ListNode temphead = head; while (tempeven != null && tempeven.next != null) { temphead.next = temphead.next.next; temphead = temphead.next; tempeven.next = tempeven.next.next; tempeven = tempeven.next; } temphead.next = even; return head; } }
旋转链表 题目 解析
构成一个环,再跑。
class Solution { public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null) return head; int n = 1; ListNode tail = head; while (tail.next != null) { tail = tail.next; n++; } tail.next = head; for (int i = 0; i < n - (k % n); i++) { head = head.next; tail = tail.next; } tail.next = null; return head; } }

浙公网安备 33010602011771号