快慢指针

匿名 (未验证) 提交于 2019-12-02 23:26:52

做LeetCode碰到两个快慢指针运用的题目,记录一下,当然这个东西应用的地方肯定不止下面这两个了,以后要是碰到就再更新

快慢指针:

这里快慢实际是指他们移动的步数,一个一次移动多个位置(一般二),一个移动一个

1,判断链表里是否存在环

题目描述:

给定一个链表,判断链表中是否有环。

pospos-1,则在该链表中没有环。

思路:快指针和慢指针同时往链表后面移动,如果快指针到达NULL,说明链表以NULL为结尾,没有环。如果快指针追上慢指针(即两个相等),则表示有环。

代码:

/**  * Definition for singly-linked list.  * class ListNode {  *     int val;  *     ListNode next;  *     ListNode(int x) {  *         val = x;  *         next = null;  *     }  * }  */ public class Solution {     public boolean hasCycle(ListNode head) {          if (head==null) {             return false;         }         ListNode slow = head;         ListNode fast = head;         while(fast!=null&&fast.next!=null) {             slow = slow.next;             fast = fast.next.next;             if (fast==slow) {                 return true;             }         }         return false;     } }
View Code

二,一个排序链表里找到中位数

这里其实就是倍数关系了,假设把快慢指针比作一条道路上的车,快车的速度是慢车的两倍,同时出发,那么快车到达终点的时候慢车就在这条路的中间位置!

但是到链表里就得注意元素个数奇偶的问题,奇数直接返回slow,偶数的话,返回slow和slow下一个数的和除2

代码:

package com.mine.leetcode;  import java.util.List;  public class Solution141 {     public int getMidElement(ListNode head) {         ListNode fast = head;         ListNode slow = head;         while(fast!=null&&slow!=null) {             //System.out.println("-"+fast.val);             if(fast.next==null)                 return slow.val;             else if(fast.next!=null&&fast.next.next==null)                 return (slow.val+slow.next.val)/2;             else {                 fast = fast.next.next;                 slow = slow.next;             }         }         return 666;     }     public static ListNode generateListByArray(int[] nums) {         ListNode head = new ListNode(0);         ListNode temp = head;         for(int i = 0;i < nums.length;i++) {             temp.next = new ListNode(nums[i]);             temp = temp.next;         }         return head.next;     }          public static void main(String[] args) {         int[] nums = {1,2,3,4,5,6,7};         System.out.println(new Solution141().getMidElement(generateListByArray(nums)));     } }
View Code

三,输出链表的倒数第K个节点

也是跟上面差不多的原理,第一个指针从链表的头指针开始遍历向前走k-1步,第二个指针保持不动;从第K步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个指针到达链表的尾节点时候,第二个指针正好是倒数第K个节点

代码:

package com.mine.leetcode;  import java.util.List;  public class Solution141 {     // 查找单链表中倒数第K个结点       public ListNode GetKthNode(ListNode pHead, int k) // 函数名前面的R代表反向       {           if(k == 0 || pHead == null) // 这里k的计数是从1开始的,若k为0或链表为空返回NULL               return null;                  ListNode pAhead = pHead;           ListNode pBehind = pHead;               for(int i=0;i<k-1;i++){                  pAhead=pAhead.next;                  if(pAhead==null)  return null;//当链表长度小于k时候,返回Null               }           while(pAhead.next != null)  // 前后两个指针一起向前走,直到前面的指针指向最后一个结点           {               pBehind = pBehind.next;               pAhead = pAhead.next;           }           return pBehind;  // 后面的指针所指结点就是倒数第k个结点       }        public static void main(String[] args) {         int[] nums = {1,2,3,4,5,6,7};         System.out.println(new Solution141().GetKthNode(generateListByArray(nums), 2).val);     } }
View Code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!