算法训练营Day4| 链表Part2

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

  • 自我尝试
    • 代码
      /**
       * Definition for singly-linked list.
       * public class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode() {}
       *     ListNode(int val) { this.val = val; }
       *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
       * }
       */
      class Solution {
          public ListNode swapPairs(ListNode head) {
              // 因为head可能会变,保留dummyHead更加方便操作
              ListNode dummyHead = new ListNode(-1, head);
              ListNode pre = dummyHead;
              ListNode cur = dummyHead.next;
              ListNode tmp;
              // cur为奇数位node.当cur.next为null说明不需要换。不为null,按部就班换
              while(cur!=null && cur.next!=null){
                  // 记录下第三个
                  tmp = cur.next.next;
                  // 串上头
                  pre.next = cur.next;
                  // 第二个指向第一个,调换!
                  cur.next.next = cur;
                  // 将第三个地址留回来
                  cur.next = tmp;
                  pre = cur;
                  cur = cur.next;
              }
              return dummyHead.next;
          }
      }

  • 范例题解
    • 代码
      • 递归法
        class Solution {
            public ListNode swapPairs(ListNode head) {
                // base case 退出提交
                if(head == null || head.next == null) return head;
                // 获取当前节点的下一个节点
                ListNode next = head.next;
                // 进行递归
                ListNode newNode = swapPairs(next.next);
                // 这里进行交换
                next.next = head;
                head.next = newNode;
        
                return next;
            }
        } 

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

  • 自我尝试
    • 代码
      /**
       * Definition for singly-linked list.
       * public class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode() {}
       *     ListNode(int val) { this.val = val; }
       *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
       * }
       */
      class Solution {
          public ListNode removeNthFromEnd(ListNode head, int n) {
              if (head==null){
                  return head;
              }
              int size = 0;
              ListNode dummyHead = new ListNode(-1,head);
              ListNode pre=dummyHead;
              // count the element
              while(pre.next!=null){
                  pre = pre.next; 
                  size++;
              }
              int removIndx= size-n;
              pre = dummyHead;
              for(int i=0;i<removIndx;i++){
                  pre = pre.next;
              }
              pre.next=pre.next.next;
      
              return dummyHead.next;
          }
      }

    • 收获
      • 思路:遍历完一遍,确认了总数,然后确定要删除的index
  • 范例题解
    • 代码
      /**
       * Definition for singly-linked list.
       * public class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode() {}
       *     ListNode(int val) { this.val = val; }
       *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
       * }
       */
      class Solution {
          public ListNode removeNthFromEnd(ListNode head, int n) {
              //双指针方法
              ListNode dummyHead = new ListNode(-1,head);
              ListNode fast = dummyHead;
              ListNode slow = dummyHead;
              for(int i=0;i<n;i++){
                  fast = fast.next;
              }
              while(fast.next!=null){
                  slow=slow.next;
                  fast=fast.next;
              }
              slow.next = slow.next.next;
              return dummyHead.next;
          }
      }

    • 收获
      • 思路:双指针法——快慢指针。移除倒数n个,首先让fast指针先偏移n个index,即n+1个node。随后,fast与slow一起遍历直到fast.next为空(到底了)。此时的slow指的就是要移除node的前一个,可以直接轻松移除。
      • 注意第一个for循环里面的条件i<n,不可以等于。

面试题 02.07. 链表相交

  • 自我尝试
    • 代码-暴力法
      /**
       * Definition for singly-linked list.
       * public class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode(int x) {
       *         val = x;
       *         next = null;
       *     }
       * }
       */
      public class Solution {
          public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
              //暴力法:
              ListNode a=headA;
              while(a!=null){
                  ListNode b=headB;
                  while(b!=null){
                      if(a==b){
                          return a;
                      }
                      b=b.next;
                  }
                  a=a.next;
              }
              return null;
          }
      }

    • 收获
      • 思路:O(N*M)将每个node都比较一下。
  • 范例题解
    • 代码-迭代法
      /**
       * Definition for singly-linked list.
       * public class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode(int x) {
       *         val = x;
       *         next = null;
       *     }
       * }
       */
      public class Solution {
          public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
              ListNode a =headA;
              ListNode b =headB;
              int sizeA =0;
              int sizeB =0;
              while(a!=null){
                  sizeA++;
                  a=a.next;
              }
              while(b!=null){
                  sizeB++;
                  b=b.next;
              }
              int gap=0;
              ListNode longList;
              ListNode shortList;
              if(sizeA>sizeB){
                  longList = headA;
                  shortList = headB;
                  gap = sizeA-sizeB;
      
              }else{
                  longList = headB;
                  shortList = headA;
                  gap = sizeB-sizeA;
              }
          
              for(int i=0;i<gap;i++){
                  longList = longList.next;
              }
              while(longList!=null){
                  if(longList==shortList){
                      return longList;
                  }
                  longList=longList.next;
                  shortList=shortList.next;
              }
      
              return null;
      
      
          }
      }

             
    • 收获

142.环形链表II  

  • 自我尝试
    • 代码
      • HashMap
        /**
         * Definition for singly-linked list.
         * class ListNode {
         *     int val;
         *     ListNode next;
         *     ListNode(int x) {
         *         val = x;
         *         next = null;
         *     }
         * }
         */
        
        import java.util.HashMap;
        import java.util.Map;
        public class Solution {
            public ListNode detectCycle(ListNode head) {
                Map<ListNode, Integer> dic = new HashMap<>();
                while(head!=null){
                    if(dic.containsKey(head)){
                        return head;
                    }
                    dic.put(head,1);
                    head=head.next;
                }
                return null;
            }
        }
      • ArrayList
        /**
         * Definition for singly-linked list.
         * class ListNode {
         *     int val;
         *     ListNode next;
         *     ListNode(int x) {
         *         val = x;
         *         next = null;
         *     }
         * }
         */
        
        import java.util.ArrayList;
        public class Solution {
            public ListNode detectCycle(ListNode head) {
                ArrayList<ListNode> nlst = new ArrayList<>();
                while(head!=null){
                    if(!nlst.contains(head)){
                        nlst.add(head);
                        head=head.next;
                    }else{
                        return head;
                    }
                }
                return null;
            }
        }

  • 范例题解
    • 代码
      /**
       * Definition for singly-linked list.
       * class ListNode {
       *     int val;
       *     ListNode next;
       *     ListNode(int x) {
       *         val = x;
       *         next = null;
       *     }
       * }
       */
      
      import java.util.ArrayList;
      public class Solution {
          public ListNode detectCycle(ListNode head) {
              if (head==null){
                  return null;
              }
              ListNode fast = head;
              ListNode slow = head;
              while(fast.next!=null && fast.next.next!=null){
                  fast = fast.next.next;
                  slow = slow.next;
                  if(fast==slow){
                      ListNode tmp = head;
                      while(tmp!=slow){
                          tmp= tmp.next;
                          slow = slow.next;
                      }
                      return slow;
      
                  }
              }
              return null;
          }
      }

       
    • 收获
      • 思路:这个方法很数学。1.通过快慢指针确定是否是环 2. 通过推导确定相遇位置,进而推出入口点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值