defaddAtIndex(self, index: int, val: int) -> None: if index > self.size: return index = max(0, index) self.size += 1 pred = self.head for _ inrange(index): pred = pred.next to_add = ListNode(val) to_add.next = pred.next pred.next = to_add
defdeleteAtIndex(self, index: int) -> None: if index < 0or index >= self.size: return self.size -= 1 pred = self.head for _ inrange(index): pred = pred.next pred.next = pred.next.next
classListNode: def__init__(self, val, next=None): self.val = val self.next = next
链表的基本操作:
获取链表的第index个节点的数值
在链表的最前面插入一个节点
在链表的最后面插入一个节点
在链表的第index个节点前面插入一个节点
删除链表的第index个节点的数值
代码题
203、移除链表元素
Python代码
1 2 3 4 5 6 7 8 9 10
classSolution: defremoveElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]: dummy = ListNode(0,head) p = dummy while p.next: if p.next.val==val: p.next=p.next.next else: p = p.next return dummy.next
Java代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution{ public ListNode removeElements(ListNode head, int val){ ListNode dummy = new ListNode(0,head); ListNode p = dummy; while(p.next!=null){ if(p.next.val==val){ p.next = p.next.next; }else{ p = p.next; } } return dummy.next; } }
707、设计链表
206、反转链表
本题如果重新定义一个新的链表会浪费存储空间,最好的思路是直接在链表本身上进行操作。
思路1:头插法
需要先进行判断
1 2
ifnot head ornot head.next: return head
1 2 3 4 5 6 7 8 9 10 11
classSolution: defreverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: # 头插法 p = head dummy = ListNode(0) while p: tmp = p.next p.next = dummy.next dummy.next = p p = tmp return dummy.next
java代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution{ public ListNode reverseList(ListNode head){ ListNode node = new ListNode(); ListNode cur = head; while(cur!=null){ ListNode tmp = cur.next; cur.next = node.next; node.next = cur; cur = tmp; } return node.next;
} }
思路2:双指针
从头往后进行遍历
1 2 3 4 5 6 7 8 9 10 11
classSolution: defreverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: # 双指针 pre = None p = head while p: tmp = p.next p.next = pre pre = p p = tmp return pre
classSolution: defreverseBetween(self, head: Optional[ListNode], left: int, right: int) -> Optional[ListNode]: # 记录left到right之间的位置 然后将其逆序再反转 dummy = ListNode(0, head) p = dummy for _ inrange(left-1): p = p.next # p现在指向第一个中断点 cur = p.next tail = cur prev = None for _ inrange(right-left+1): tmp = cur.next cur.next = prev prev = cur # 头指针,每次都指向新插入的节点 cur = tmp p.next = prev tail.next = cur return dummy.next
234、回文链表
思路:遍历一遍链表,然后使用双指针判断是否是回文的。
1 2 3 4 5 6 7 8 9
classSolution: defisPalindrome(self, head: Optional[ListNode]) -> bool: p = head res = [] while p: res.append(p.val) p = p.next # print(res) return res==res[::-1]
classSolution: defhasCycle(self, head: Optional[ListNode]) -> bool: ifnot head ornot head.next: returnFalse slow = head fast = head.next while slow!=fast: ifnot fast ornot fast.next: returnFalse slow = slow.next fast = fast.next.next returnTrue
142、环形链表II
哈希表解决
1 2 3 4 5 6 7 8 9 10
classSolution: defdetectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: myhash = {} p = head while p: if p in myhash: return p myhash[p] = p p = p.next returnNone
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicclassSolution{ public ListNode detectCycle(ListNode head){ ListNode p = head; HashMap<ListNode,ListNode> myhash = new HashMap<>(); while(p!=null){ if (myhash.containsKey(p)){ return p; } myhash.put(p,p); p = p.next; } returnnull; } }
classSolution: defdeleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: dummy = ListNode(101, head) p = dummy while p and p.next: if p.val == p.next.val: p.next = p.next.next else: p = p.next return dummy.next
82、删除排序链表中的重复元素II(*)
哈希表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: defdeleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: myhash = {} dummy = ListNode(101,head) p = head while p: myhash[p.val] = myhash.get(p.val,0)+1 p = p.next # print(myhash) p = dummy.next prev = dummy while p: if myhash[p.val]>1: prev.next = p.next else: prev = p p = p.next return dummy.next