• 快慢指针


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

    快慢指针:

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

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

    题目描述:

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

    为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -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
  • 相关阅读:
    activiti5.13工作流系列(一)-初识
    java通过http调用服务
    Eclipse快捷键大全(转载)
    java作用域-转
    ajax两种不同方式的不同结果
    MySQL索引背后的数据结构及算法原理 --转
    解决json包含html标签无法显示的问题
    js下的sleep实现
    json使用
    比较靠谱的网页分页代码-转
  • 原文地址:https://www.cnblogs.com/Yintianhao/p/10687155.html
Copyright © 2020-2023  润新知