判断环形链表

判断环形链表

题目示意

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

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环

示例1

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例2

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

分析

判断是否环的问题,可以类似转化为判断是否重复的问题,那么判断重复问题我们一般首先考虑哈希表来做,如果问题对空间有限制,用双指针策略来做

先来看看简单的哈希表策略

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
 //hashMethod
 public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<>();

        while (head!=null){
            if (set.contains(head)){ return true ;}
            else {
                set.add(head);
                head = head.next;
            }
        }
           return  false ;
    }
}

  • 不用像之前判断重复问题一样,得先把链表结点放入哈希表,在判断环问题,我们只需边遍历边入表即可

双指针

public class Solution {
    public boolean hasCycle(ListNode head) {
        if (head==null||head.next==null) return  false ; 
        ListNode slow = head ; 
        ListNode fast = head.next ; 
        
        while(fast!=null&&fast.next!=null){
            if (fast==slow) return true ; 
            slow = slow.next ; 
            fast = fast.next.next ; 
        }
        
        return false ;
    }
}

这个…直接看代码能看懂吧
删除排序链表(或数组)中的重复元素这个问题中,我们也使用了双指针,可以类比看看

==========update by 2020 4/16 ==================

C++源代码(经VS2015、devC++运行通过)

#include "stdio.h"    
#include "string.h"
#include "ctype.h"      
#include "stdlib.h"   
#include "io.h"  
#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */


Status visit(ElemType c)
{
	printf("%d ", c);
	return OK;
}


typedef struct ListNode
{
	ElemType val;
	struct ListNode *next;
}ListNode;
typedef struct ListNode *LinkList; /* 定义LinkList */

/* 初始化顺序线性表 */
Status InitList(LinkList *L)
{
	*L = (LinkList)malloc(sizeof(ListNode)); /* 产生头结点,并使L指向此头结点 */
	if (!(*L)) /* 存储分配失败 */
		return ERROR;
	(*L)->val = NULL;
	(*L)->next = NULL; /* 指针域为空 */

	return OK;
}


/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L, int i, ElemType e)
{
	int j;
	LinkList p, s;
	p = *L;
	j = 1;
	while (p && j < i)     /* 寻找第i个结点 */
	{
		p = p->next;
		++j;
	}
	if (!p || j > i)
		return ERROR;   /* 第i个元素不存在 */
	s = (LinkList)malloc(sizeof(ListNode));  /*  生成新结点(C语言标准函数) */
	s->val = e;
	s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
	p->next = s;          /* 将s赋值给p的后继 */
	return OK;
}



/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(LinkList L)
{
	LinkList p = L->next;
	while (p)
	{
		visit(p->val);
		p = p->next;
	}
	printf("\n");
	return OK;
}

int ListLength(LinkList L)
{
	int i = 0;
	LinkList p = L->next; /* p指向第一个结点 */
	while (p)
	{
		i++;
		p = p->next;
	}
	return i;
}

Status CircleLink(int len, LinkList *L ,int pos) {
	if (pos!=(-1))  //若pos=-1则代表不设环
	{
	LinkList p,s;
	p = *L; 
	s = *L; 
	/*找到末尾指针*/

		for (int i = 1; i <= len; i++) {
			p = p->next;
		}
		for (int j = 1; j <= pos; j++) {
			s = s->next;
		}
		p->next = s->next;

		return 1;
	}

	return 0; 
}

int main()
{
	LinkList L;
	Status i;
	int len,pos; 
	
	/*1.初始化单链表*/
	i = InitList(&L);


	/*2.依次采用尾插法插入abcde元素*/

	ListInsert(&L, 1, 3);
	ListInsert(&L, 2, 2);
	ListInsert(&L, 3, 0);
	ListInsert(&L, 4, -4);

	ListTraverse(L);

	len = ListLength(L); 
	
	printf("请输入位置position");
	scanf_s("%d", &pos); 
	
	
	i = CircleLink(len, &L, pos); 
	if (i) 
	{ printf("true\nthe position = %d\n",pos); 
	}
	else {
		printf("false");
	}

	system("pause");

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值