【Leetcode】287. 寻找重复数(数组模拟链表的快慢指针法)
寻找重复数

根据题意,数组中的数字都在1~n之间,所以数字的范围是小于数组的范围的,数组的元素可以和数组的索引相联系。
例如:nums[0] = 1 即可以将nums[0]作为索引 通过nums[0] 可以访问到nums[1],以此类推。

如左图所示,环的入口就是重复元素。
那么问题就转化为了如何找到入环的第一个节点的问题。时间复杂度为O(n)
慢指针可以定义为:nums[slow] 快指针可以定义为:nums[nums[fast]]
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0;
int fast = 0;
slow = nums[slow];
fast = nums[nums[fast]];
while(slow != fast){
slow = nums[slow];
fast = nums[nums[fast]];
}
fast = 0;
while(slow != fast){
fast = nums[fast];
slow = nums[slow];
}
return slow;
}
}
【下面顺便复习一下关于链表的题】
环形链表
141. 环形链表
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null || head.next.next == null){
return false;
}
ListNode slow = head.next;
ListNode fast = head.next.next;
while(slow != fast){
if(fast.next == null || fast.next.next == null){
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
}
}
142. 环形链表 II
2. 寻找入环第一个节点:使用快慢指针。快指针走两步,慢指针走一步,一起走到相遇节点后,慢指针不动,快指针回到原点,然后快慢指针再一起一步一步地走,相遇点即入环的第一个节点。
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null|| head.next.next == null){
return null;
}
ListNode slow = head.next;
ListNode fast = head.next.next;
while(slow!=fast){
if(fast.next == null || fast.next.next == null){
return null;
}
slow = slow.next;
fast = fast.next.next;
}
fast = head;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
相交链表
- 一个有环,一个无环:不可能相交
- 两个都无环:需要判断是否相交。相交,则是第一个相交节点。不相交,返回null。
- 两个都有环
- 两个各自一个环:不相交,返回null
- 两个共用一个环
- 先找入环的第一个节点 loop1和loop2
- 入环节点一样:loop1==loop2 可以转化为无环的相交问题,终止节点变成了loop节点。
- 入环节点不一样:loop1继续向下走直到遇到loop2,如果没有遇到则是两个各自一个环。返回loop1或loop2。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA;
ListNode curB = headB;
int lenA = 0, lenB = 0;
while(curA != null){
curA = curA.next;
lenA ++;
}
while(curB != null){
curB = curB.next;
lenB ++;
}
//A始终是长链表
curA = lenA > lenB ? headA:headB;
curB = curA == headA? headB:headA;
int del = Math.abs(lenA - lenB);
while(del > 0){
curA = curA.next;
del--;
}
while(curA!=curB){
if(curA.next == null || curB.next == null){
return null;
}
curA = curA.next;
curB = curB.next;
}
return curA;
}
}
两个都有环相交的情况:
【待续】
【Leetcode】287. 寻找重复数(数组模拟链表的快慢指针法)的更多相关文章
- Java实现 LeetCode 287 寻找重复数
287. 寻找重复数 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 ...
- LeetCode | 287. 寻找重复数
特别感谢LeetCode大佬陈牧远的科普知识 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找 ...
- [LeetCode]287. 寻找重复数(二分)
题目 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数,找出这个重复的数. 示例 1: 输入: [ ...
- leetcode 287寻找重复数
这道题用STL容器就很好写了,可以用set也可以用map, 用unordered_map的C++代码如下: class Solution { public: int findDuplicate(vec ...
- LeetCode:寻找重复数【287】
LeetCode:寻找重复数[287] 题目描述 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数.假设只有一个重复的整数 ...
- Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number)
Leetcode之二分法专题-287. 寻找重复数(Find the Duplicate Number) 给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 ...
- 287. 寻找重复数 Java解法
287. 寻找重复数 这题的难点就在于下面的说明了,我们先不管下面的那些说明的要求,用常规的解法来解答下上的题目. 排序思想解法 先把原来的数组进行排序,然后逐个遍历,一旦发现后一个元素和当前的元素相 ...
- UVA11988-Broken Keyboard(数组模拟链表)
Problem UVA11988-Broken Keyboard Accept: 5642 Submit: 34937 Time Limit: 1000 mSec Problem Descripti ...
- C - Boxes in a Line 数组模拟链表
You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simul ...
随机推荐
- 瑞幸咖啡还是星巴克,一杯下午茶让我明白 设计模式--模板方法模式(Template Method Pattern)
简介 Define the skeleton of an algorithm in an operation,deferring some steps to subclasses.Template M ...
- 数据结构--栈(附上STL栈)
定义: 栈是一种只能在某一端插入和删除数据的特殊线性表.他按照先进先出的原则存储数据,先进的数据被压入栈底,最后进入的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后被压入栈的,最先弹出).因此栈 ...
- 题目分享Y
题意:给出一个n个点n条边的图且不一定连通(原题面为每个节点出度为1),相邻节点不能同时被选,每个节点有其对应价值,求最多能获得多少价值?n<=1e6,val[i]<=1e6 分析:很容易 ...
- 最长公共子串(Longest common substring)
问题描述: 给定两个序列 X=<x1, x2, ..., xm>, Y<y1, y2, ..., yn>,求X和Y长度最长的公共子串.(子串中的字符要求连续) 这道题和最长公共 ...
- ASP.NET Core MVC 如何获取请求的参数
一次HTTP请求,就是一次标准IO操作.请求是I,是输入:响应式O,是输出.任何web开发框架,其实都是在干这两件事: 接受请求并进行解析获取参数 根据参数进行渲染并输出响应内容 所以我们学习一个框架 ...
- Codeforces 1332 D. Walk on Matrix(构造矩阵)
怎么构造呢? \(首先我们不可能去构造一个2000*2000的矩阵,那太复杂了\) \(也许我们可以看看2*2的矩阵??\) \[\left[ \begin{matrix} x&y\\ z&a ...
- POJ3255(次最短路)
描述 求1到n的次最短路 开个\(dis[maxn][2]\)的储存距离的二维数组,0储存最短路,1储存次短路 初始化全为正无穷,\(dis[1][0]=0;\) 然后遍历更新时,先尝试更新最短路和次 ...
- P2774 方格取数问题 网络流
题目: P2774 方格取数问题 题目背景 none! 题目描述 在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大. ...
- Spring源码阅读 之 bean的注册
在前面我们已经学习了配置的加载,读取,解析.现在我们已经能够将一份配置转变成对应的一个个beandefinition了,我们知道Spring是一个IOC的容器,那么我们如何将这个一个个beandefi ...
- Matlab2016b线性规划函数linprog的几个问题
一.如何设置算法为单纯型法: options = optimoptions('linprog','Algorithm','dual-simplex') 二.linprog的参数用法: [x,Fval, ...