203 移除链表元素

`YTSMLL_KW@XUQ5OQH6}ELM.png
61M~XKLTYH1LGSJ`CV266GP.jpg

思路:

删除结点的步骤
找到该结点的前一个结点
进行删除操作

代码

  1. #虚拟头节点
  2. class Solution:
  3. def removeElements(self, head: ListNode, val: int) -> ListNode:
  4. dummyHead = ListNode(-1, head)
  5. cur = dummyHead
  6. while cur.next:
  7. if cur.next.val == val:
  8. cur.next = cur.next.next
  9. else:
  10. cur = cur.next
  11. return dummyHead.next
  12. #递归
  13. struct ListNode* removeElements(struct ListNode* head, int val){
  14. if (head == NULL) {
  15. return NULL;
  16. }
  17. head->next = removeElements(head->next, val);
  18. return head->val == val ? head->next : head;
  19. }
  20. #栈
  21. class Solution {
  22. public ListNode removeElements(ListNode head, int val) {
  23. Stack<ListNode> stack = new Stack<ListNode>();
  24. while (head != null) {
  25. if (head.val != val) {
  26. stack.push(head);
  27. }
  28. head = head.next;
  29. }
  30. while (!stack.isEmpty()) {
  31. stack.peek().next = head;
  32. head = stack.pop();
  33. }
  34. return head;
  35. }
  36. }
  37. #迭代
  38. class Solution:
  39. def removeElements(self, head: ListNode, val: int) -> ListNode:
  40. while head and head.val == val:
  41. head = head.next
  42. if not head: return
  43. pre = head
  44. while pre.next:
  45. if pre.next.val == val:
  46. pre.next = pre.next.next
  47. else:
  48. pre = pre.next
  49. return head
  1. //删除头结点时另做考虑(由于头结点没有前一个结点)
  2. class Solution {
  3. public ListNode removeElements(ListNode head, int val) {
  4. //删除值相同的头结点后,可能新的头结点也值相等,用循环解决
  5. while(head!=null&&head.val==val){
  6. head=head.next;
  7. }
  8. if(head==null)
  9. return head;
  10. ListNode prev=head;
  11. //确保当前结点后还有结点
  12. while(prev.next!=null){
  13. if(prev.next.val==val){
  14. prev.next=prev.next.next;
  15. }else{
  16. prev=prev.next;
  17. }
  18. }
  19. return head;
  20. }
  21. }
  22. //添加一个虚拟头结点,删除头结点就不用另做考虑
  23. class Solution {
  24. public ListNode removeElements(ListNode head, int val) {
  25. //创建一个虚拟头结点
  26. ListNode dummyNode=new ListNode(val-1);
  27. dummyNode.next=head;
  28. ListNode prev=dummyNode;
  29. //确保当前结点后还有结点
  30. while(prev.next!=null){
  31. if(prev.next.val==val){
  32. prev.next=prev.next.next;
  33. }else{
  34. prev=prev.next;
  35. }
  36. }
  37. return dummyNode.next;
  38. }
  39. }
  40. //递归
  41. class Solution {
  42. public ListNode removeElements(ListNode head, int val) {
  43. if(head==null)
  44. return null;
  45. head.next=removeElements(head.next,val);
  46. if(head.val==val){
  47. return head.next;
  48. }else{
  49. return head;
  50. }
  51. }
  52. }

206反转链表

17)XXKE3AB6H)OVLZU]UYPT.png$5RW$%WRIRRAQ}TM7)WVDM9.pngN{45`XBN3$]GKL{E0O8}I7F.png

思路:

双指针迭代:
申请两个指针,第一个指针叫 pre,最初是指向 null 的。第二个指针 cur 指向 head,然后不断遍历 cur。
每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。

递归:
递归的两个条件:
终止条件是当前节点或者下一个节点==null
在函数内部,改变节点的指向,也就是 head 的下一个节点指向 head 递归函数那句
head.next.next = head( head 的下一个节点指向head。
递归函数中每次返回的 cur 其实只最后一个节点,在递归函数内部,改变的是当前节点的指向。

代码

  1. #迭代
  2. class Solution(object):
  3. def reverseList(self, head):
  4. """
  5. :type head: ListNode
  6. :rtype: ListNode
  7. """
  8. # 申请两个节点,pre和 cur,pre指向None
  9. pre = None
  10. cur = head
  11. # 遍历链表,while循环里面的内容其实可以写成一行
  12. # 这里只做演示,就不搞那么骚气的写法了
  13. while cur:
  14. # 记录当前节点的下一个节点
  15. tmp = cur.next
  16. # 然后将当前节点指向pre
  17. cur.next = pre
  18. # pre和cur节点都前进一位
  19. pre = cur
  20. cur = tmp
  21. return pre
  22. #递归
  23. class Solution(object):
  24. def reverseList(self, head):
  25. """
  26. :type head: ListNode
  27. :rtype: ListNode
  28. """
  29. # 递归终止条件是当前为空,或者下一个节点为空
  30. if(head==None or head.next==None):
  31. return head
  32. # 这里的cur就是最后一个节点
  33. cur = self.reverseList(head.next)
  34. # 这里请配合动画演示理解
  35. # 如果链表是 1->2->3->4->5,那么此时的cur就是5
  36. # 而head是4,head的下一个是5,下下一个是空
  37. # 所以head.next.next 就是5->4
  38. head.next.next = head
  39. # 防止链表循环,需要将head.next设置为空
  40. head.next = None
  41. # 每层递归函数都返回cur,也就是最后一个节点
  42. return cur
  1. //迭代
  2. class Solution {
  3. public ListNode reverseList(ListNode head) {
  4. //申请节点,pre和 cur,pre指向null
  5. ListNode pre = null;
  6. ListNode cur = head;
  7. ListNode tmp = null;
  8. while(cur!=null) {
  9. //记录当前节点的下一个节点
  10. tmp = cur.next;
  11. //然后将当前节点指向pre
  12. cur.next = pre;
  13. //pre和cur节点都前进一位
  14. pre = cur;
  15. cur = tmp;
  16. }
  17. return pre;
  18. }
  19. }
  20. //递归
  21. class Solution {
  22. public ListNode reverseList(ListNode head) {
  23. //递归终止条件是当前为空,或者下一个节点为空
  24. if(head==null || head.next==null) {
  25. return head;
  26. }
  27. //这里的cur就是最后一个节点
  28. ListNode cur = reverseList(head.next);
  29. //这里请配合动画演示理解
  30. //如果链表是 1->2->3->4->5,那么此时的cur就是5
  31. //而head是4,head的下一个是5,下下一个是空
  32. //所以head.next.next 就是5->4
  33. head.next.next = head;
  34. //防止链表循环,需要将head.next设置为空
  35. head.next = null;
  36. //每层递归函数都返回cur,也就是最后一个节点
  37. return cur;
  38. }
  39. }