LeetCode.203 移除链表元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
class Solution { public ListNode removeElements(ListNode head, int val) { ListNode sentinel = new ListNode (-1, head);
ListNode p = sentinel; while (p.next != null) {
if(p.next.val == val) { p.next = p.next.next; }else { p = p.next; }
}
return sentinel.next; } }
|
注意链表可能为空,引入哨兵节点处理这种Corner Case即可。
LeetCode.707 设计链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| class ListNode { public int val; public ListNode next;
ListNode () {}; ListNode (int val, ListNode next) { this.val = val; this.next = next; } }
class MyLinkedList { private int size; private ListNode sentinel;
MyLinkedList () { size = 0; sentinel = new ListNode(-1, null); }; private static int getIndex (int index, ListNode node) { if (index == 0) { return node.val; }else { return getIndex(index - 1, node.next); } }
public int get(int index) { if (index < 0 || index >= size) { return -1; }else { return getIndex(index + 1, sentinel); }
} public void addAtHead(int val) { sentinel.next = new ListNode(val, sentinel.next); size++; } public void addAtTail(int val) { ListNode p = sentinel; while ( p.next != null) { p = p.next; } p.next = new ListNode(val , null); size++; } public void addAtIndex(int index, int val) { if(index <= 0) { addAtHead(val); }else if (index > size) { return; }else { ListNode p = sentinel; while ( index > 0) { p = p.next; index--; } p.next = new ListNode(val, p.next); size++; } } public void deleteAtIndex(int index) { if (index < 0 || index >= size) { return; }else { ListNode p = sentinel; while ( index > 0) { p = p.next; index--; } p.next = p.next.next; size--; } } }
|
关于链表设计的一些思考
- 使用List类封装原来裸露的节点结构
- 封装的好处还在于可以提供一些如size,lastIndex的field方便链表操作
- 使用哨兵节点减少对corner case的考虑
- 使用私有静态方法递归的对内部节点进行操作
LeetCode.206 反转链表
反转链表的核心在于保存当前指向节点的prev和next节点信息,因此使用一个prev指针和一个temp指针记录下信息,之后只要递归或者循环遍历整个链表即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; ListNode cur = head; ListNode temp = null; while (cur != null) { temp = cur.next; cur.next = prev; prev = cur; cur = temp; } return prev; }
public ListNode reverseListRecurrsively(ListNode head) { return reverse(null, head); }
private ListNode reverse (ListNode prev, ListNode cur) { if (cur == null) { return prev; } else { ListNode temp = cur.next; cur.next = prev; return reverse(cur, temp); } } }
|