【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 ...
随机推荐
- GPTL—练习集—006树的遍历
#include<bits/stdc++.h> using namespace std; typedef int daTp;//datatype typedef struct BTNode ...
- Linux下Wiki服务器的搭建
一.准备工作 1.软件下载和安装 最主要的就是安装好Mysql+apache+PHP 测试apache能够解析index.php文件后就可以. mysql安装好后: adduser wiki #给 ...
- #Week7 Neural Networks : Learning
一.Cost Function and Backpropagation 神经网络的损失函数: \[J(\Theta) = - \frac{1}{m} \sum_{i=1}^m \sum_{k=1}^K ...
- Java——Java自动装箱和拆箱
一.什么是自动装箱和拆箱: 我们知道java为8种基本类型分别提供了对应的包装类型,在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行: Integer i=new I ...
- Java——运算符那些事
&& 逻辑与 &&先运算&&左边的算式,如果为假,则直接停止,后面不管有多少运算式都不再运算,如果为真则继续判断后面的式子,只有所有的条件全部成立,才会 ...
- .net core HttpClient 使用之掉坑解析(一)
一.前言 在我们开发当中经常需要向特定URL地址发送Http请求操作,在.net core 中对httpClient使用不当会造成灾难性的问题,这篇文章主要来分享.net core中通过IHttpCl ...
- Golang遍历删除数组
Golang 做数字切片 package main import "fmt" /*遍历删除数组示例*/ func main() { //定义一个数组 a1 := []int{1, ...
- srping mvc RequestMapping实现
spring mvc中定义请求的url只需要在方法上添加注解: @RequestMapping("aa.mvc")即可定义访问的url地址,但是你是否有考虑过为什么添加这个注解就可 ...
- Docker学习笔记(二):端口映射与容器互联
端口映射 使用docker run时,可以指定-P(大写)与-p(小写)参数映射端口. docker run -P -P(大写)会随机映射一个端口到容器的内部端口 -> [feifei@ffma ...
- python实现登录密码重置简易操作
需求: 1.用户输入密码正确登录 2.用户输入密码错误退出并调用函数继续输入 3.用户输入密码符合原先给定的一个值时,允许用户重置密码,并且可以用新密码登录 4.输入三次后禁止输入 虽然贴别的简单,但 ...