删除相关

203.移除链表元素

  1. class Solution {
  2. public ListNode removeElements(ListNode head, int val) {
  3. //设置虚拟头结点,可以将头节点和其他节点同等对待
  4. ListNode virtualNode = new ListNode();
  5. virtualNode.next = head;
  6. ListNode idx = virtualNode;
  7. while(idx.next != null){
  8. if (idx.next.val == val){
  9. idx.next = idx.next.next;
  10. }else{
  11. idx = idx.next;
  12. }
  13. }
  14. return virtualNode.next;
  15. }
  16. }

237. 删除链表中的节点

  1. class Solution {
  2. public void deleteNode(ListNode node) {
  3. //既然不能先删除自己,那就把自己的值变成儿子,再把儿子的位置让给孙子
  4. node.val = node.next.val;
  5. node.next = node.next.next;
  6. }
  7. }

19.删除链表的倒数第N个节点

  1. //正常版本很好过,如何一遍解决呢?
  2. //快慢指针
  3. public ListNode removeNthFromEnd(ListNode head, int n) {
  4. ListNode hair = new ListNode(0, head);
  5. ListNode fast = head;
  6. ListNode slow = hair;
  7. for (int i = 0; i < n; ++i){
  8. fast = fast.next;
  9. }
  10. while (fast != null){
  11. fast = fast.next;
  12. slow = slow.next;
  13. }
  14. //此时slow已经到了倒数第n个节点的前一个节点
  15. slow.next = slow.next.next;
  16. return hair.next;
  17. }

反转相关

206. 反转链表

  1. //先添加一个节点不用进行非空判断
  2. //这其实直接把这个链表断开了,用两个指针分别指向两段链表
  3. class Solution {
  4. public ListNode reverseList(ListNode head) {
  5. ListNode prev = null; //用来遍历从null到尾节点
  6. ListNode curr = head; //用来遍历从头结点到null
  7. while (curr != null) {
  8. ListNode temp = curr.next;
  9. curr.next = prev;
  10. prev = curr;
  11. curr = temp;
  12. }
  13. return prev;
  14. }
  15. }

92. 反转链表 II

  1. class Solution {
  2. public ListNode reverseBetween(ListNode head, int left, int right) {
  3. //设置虚拟头结点是这类问题的一般做法
  4. ListNode dummyNode = new ListNode(-1);
  5. dummyNode.next = head;
  6. //找到待反转区域的前一个节点
  7. ListNode pre = dummyNode;
  8. for (int i = 1; i < left; ++i){
  9. pre = pre.next;
  10. }
  11. ListNode cur = pre.next;
  12. ListNode temp;
  13. for (int i = left; i < right; ++i){
  14. //这里为什么是right呢,因为五个节点只需要移动四次就可以了
  15. //即left到right-1
  16. temp = cur.next;
  17. //注意赋值顺序,画个图
  18. cur.next = temp.next;
  19. temp.next = pre.next;
  20. pre.next = temp;
  21. }
  22. return dummyNode.next;
  23. }
  24. }

234. 回文链表

交换相关

24. 两两交换链表中的节点

  1. class Solution {
  2. public ListNode swapPairs(ListNode head) {
  3. ListNode dummyNode = new ListNode();
  4. dummyNode.next = head;
  5. ListNode temp = dummyNode;
  6. while(temp.next != null && temp.next.next != null){
  7. ListNode node1 = temp.next;
  8. ListNode node2 = temp.next.next;
  9. temp.next = node2;
  10. node1.next = node2.next;
  11. node2.next = node1;
  12. temp = node1;
  13. }
  14. return dummyNode.next;
  15. }
  16. }

25. K 个一组翻转链表

  1. class Solution {
  2. public ListNode reverseKGroup(ListNode head, int k) {
  3. ListNode dummyHead = new ListNode();
  4. dummyHead.next = head;
  5. int size = 0;
  6. ListNode cur = head;
  7. while(cur != null){
  8. cur = cur.next;
  9. size ++;
  10. }
  11. int quotient = size / k;
  12. ListNode headK = dummyHead;
  13. cur = headK.next;
  14. ListNode temp;
  15. for (int i = 0; i < quotient; ++i){ //要反转几次
  16. for (int j = 0; j < k-1; ++j){ //本次反转要反转几个节点,这里应该是移动几个节点而不是反转几个节点
  17. //这个k-1很重要
  18. temp = cur.next;
  19. cur.next = temp.next;
  20. temp.next = headK.next;
  21. headK.next = temp;
  22. }
  23. headK = cur;
  24. cur = cur.next;
  25. }
  26. return dummyHead.next;
  27. }
  28. }