def reverseList(self, head: ListNode) -> ListNode:
pre = None
curt = head
while curt != None:
nxt = curt.next
curt.next = pre
pre = curt
curt = nxt
return pre
Use a curt pointer and a nxt pointer to move from head. Detect if curt.val == nxt.val then remove nxt node.
def deleteDuplicates(self, head: ListNode) -> ListNode:
curt = head
while curt is not None:
nxt = curt.next
if nxt and nxt.val == curt.val:
curt.next = nxt.next
else:
curt = curt.next
return head
Use dummy node, and a current node starts at dummy. While the first and second list is not null, add the smaller node and move forward.
When end, detect the unfinished list, add to the end.
Use two stacks to store two lists separately. Pop node and construct new node, insert between dummy and dummy.next.
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
while (l1 != null) {
s1.add(l1.val);
l1 = l1.next;
}
while (l2 != null) {
s2.add(l2.val);
l2 = l2.next;
}
int carry = 0;
ListNode dummy = new ListNode(0);
while (!s1.isEmpty() || !s2.isEmpty()) {
int one = s1.isEmpty() ? 0 : s1.pop();
int two = s2.isEmpty() ? 0 : s2.pop();
int sum = one + two + carry;
ListNode curt = new ListNode(sum % 10);
carry = sum / 10;
curt.next = dummy.next;
dummy.next = curt;
}
if (carry == 1) dummy.val = 1;
return dummy.val == 1 ? dummy : dummy.next;
}
def hasCycle(self, head: ListNode) -> bool:
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
return True
return False
def detectCycle(self, head: ListNode) -> ListNode:
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
if fast == slow:
fast = head
while fast != slow:
fast = fast.next
slow = slow.next
return fast
return None
def swapPairs(self, head: ListNode) -> ListNode:
if head is None or head.next is None:
return head
dummy = ListNode(-1)
dummy.next = head
pre = dummy
curt = head
while curt is not None and curt.next is not None:
nxt = curt.next
curt.next = nxt.next
nxt.next = pre.next
pre.next = nxt
pre = curt
curt = pre.next
return dummy.next
def oddEvenList(self, head: ListNode) -> ListNode:
if not head:
return None
even = head
odd = head.next
oddhead = odd
while odd and odd.next:
even.next = odd.next
even = even.next
odd.next = even.next
odd = odd.next
even.next = oddhead
return head
记录一个pre,把pre移动到开始reverse的前面
pre不动,把后面的reverse,把next接在pre和pre.next 中间
Return dummy.next
T: O(n) S: O(1) in-place
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
for (int i = 0; i < m - 1; i++) {
pre = pre.next;
}
ListNode curt = pre.next;
for (int i = 0; i < n - m; i++) {
ListNode next = curt.next;
curt.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
dummy = ListNode(-1)
dummy.next = head
fast = dummy
slow = dummy
i = 0
while i <= n and fast:
fast = fast.next
i += 1
while fast:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
return dummy.next
def deleteDuplicates(self, head: ListNode) -> ListNode:
curt = head
while curt is not None:
nxt = curt.next
if nxt and nxt.val == curt.val:
curt.next = nxt.next
else:
curt = curt.next
return head
两个指针走,在curt.next.val == curt.val情况下移动curt
如果pre的下一个不是curt,说明有duplicate,
否则同时移动pre和curt
def deleteDuplicates(self, head: ListNode) -> ListNode:
dummy = ListNode(-1)
dummy.next = head
pre = dummy
curt = head
while curt is not None:
while curt.next is not None and curt.val == curt.next.val :
curt = curt.next
if pre.next is not curt:
pre.next = curt.next
curt = pre.next
else :
pre = pre.next
curt = pre.next
return dummy.next
def removeElements(self, head: ListNode, val: int) -> ListNode:
if head is None:
return None
dummy = ListNode(-1)
dummy.next = head
pre = dummy
curt = head
while curt is not None:
if curt.val == val:
curt = curt.next
pre.next = curt
else :
pre = pre.next
curt = curt.next
return dummy.next
def isPalindrome(self, head: ListNode) -> bool:
if not head or not head.next:
return True
fast = head
pre = head
slow = head
while fast and fast.next:
fast = fast.next.next
pre = slow
slow = slow.next
if fast:
pre = pre.next
curt = pre.next
while curt and curt.next:
nxt = curt.next
curt.next = nxt.next
nxt.next = pre.next
pre.next = nxt
fast = head
slow = pre.next
while slow and fast:
if fast.val != slow.val:
return False
fast = fast.next
slow = slow.next
return True
def partition(self, head: ListNode, x: int) -> ListNode:
largehead = ListNode(-1)
largecurt = largehead
dummy = ListNode(-1)
dummy.next = head
pre = dummy
curt = head
while curt:
if curt.val >= x:
pre.next = curt.next
curt.next = largecurt.next
largecurt.next = curt
largecurt = curt
curt = pre.next
else:
pre = pre.next
curt = curt.next
pre.next = largehead.next
return dummy.next
从 1->2->3->4, reorder it to 1->4->2->3。这样可以把list分成左右两段,反转后面的,然后相互插入形成结果。
def reorderList(self, head: ListNode) -> None:
if not head or not head.next:
return
fast = head
slow = head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
curt = slow.next
while curt and curt.next:
nxt = curt.next
curt.next = nxt.next
nxt.next = slow.next
slow.next = nxt
fast = slow.next
slow.next = None
slow = head
while fast and slow:
fn = fast.next
fast.next = slow.next
slow.next = fast
slow = fast.next
fast = fn
先一个指针找长度,另外一个指针走length - k % length,把两个指针中间接到前面去。(两个指针都从dummy 走)
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if not head or not head.next or k == 0:
return head
dummy = ListNode(-1)
dummy.next = head
length = self.getLen(head)
pre = dummy
if k % length == 0:
return dummy.next
for i in range(length - k % length):
pre = pre.next
curt = pre.next
pre.next = None
dummy.next = curt
while curt and curt.next:
curt = curt.next
if curt:
curt.next = head
return dummy.next
def getLen(self, head):
i = 0
curt = head
while curt:
i += 1
curt = curt.next
return i
Use a range pointer to detect if the range is out of scope. Reverse the part next to pre for k - 1 times.
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
ListNode range = pre;
while (true) {
for (int i = 0; i < k && range != null; i++) {
range = range.next;
if (range == null) return dummy.next;
}
ListNode curt = pre.next;
for (int i = 0; i < k - 1; i++) {
ListNode next = curt.next;
curt.next = next.next;
next.next = pre.next;
pre.next = next;
}
pre = curt;
range = pre;
}
}