Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

有赞&leetcode141:判断一个单链表是否有环 #13

Open
sisterAn opened this issue Apr 9, 2020 · 4 comments
Open

有赞&leetcode141:判断一个单链表是否有环 #13

sisterAn opened this issue Apr 9, 2020 · 4 comments

Comments

@sisterAn
Copy link
Owner

sisterAn commented Apr 9, 2020

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

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

示例 1:

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

示例 2:

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

示例 3:

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

进阶:

你能用 O(1)(即,常量)内存解决此问题吗?

附leetcode地址:leetcode

@hhshii
Copy link

hhshii commented Apr 10, 2020

当然是让引擎帮你判断啦

function hasLoop(node){
	try{
		JSON.stringify(node)
	}catch(e){
		return e.toString().includes('Converting circular')
	}
	return false
}

哈哈哈开玩笑的,其实可以用 Map 或者快慢指针解

@sisterAn
Copy link
Owner Author

sisterAn commented Apr 10, 2020

解法一:标志法

给每个已遍历过的节点加标志位,遍历链表,当出现下一个节点已被标志时,则证明单链表有环

let hasCycle = function(head) {
    while(head) {
        if(head.flag) return true
        head.flag = true
        head = head.next
    }
    return false
};

时间复杂度:O(n)

空间复杂度:O(n)

解法二:利用 JSON.stringify() 不能序列化含有循环引用的结构

let hasCycle = function(head) {
    try{
        JSON.stringify(head);
        return false;
    }
    catch(err){
        return true;
    }
};

时间复杂度:O(n)

空间复杂度:O(n)

解法三:快慢指针(双指针法)

设置快慢两个指针,遍历单链表,快指针一次走两步,慢指针一次走一步,如果单链表中存在环,则快慢指针终会指向同一个节点,否则直到快指针指向 null 时,快慢指针都不可能相遇

let hasCycle = function(head) {
    if(!head || !head.next) {
        return false
    }
    let fast = head.next.next, slow = head.next
    while(fast !== slow) {
        if(!fast || !fast.next) return false
        fast = fast.next.next
        slow = slow.next
    }
    return true
};

时间复杂度:O(n)

空间复杂度:O(1)

leetcode

@13001920223
Copy link

哈希map
init一个WeakMap用来存放已经遍历的链表,判断如果不存在set, 如果存在则是循环引用

var hasCycle = function(head) {
  let map = new WeakMap()
  if (!head && !head.next) {
    return false
  }
  while (head) {
    if (map.get(head)) {
      return true
    } else {
      map.set(head, false)
      head = head.next
    }
  }
  return false
};

@Been101
Copy link

Been101 commented Jul 15, 2020

function Node(data) {
  this.data = data
  this.next = null
}

const node1 = new Node(1)
const node2 = new Node(2)
const node4 = new Node(4)
const node6 = new Node(6)

const node3 = new Node(3)
const node5 = new Node(5)
const node9 = new Node(9)

node1.next = node2
node2.next = node4
node4.next = node6

node6.next = node5
node5.next = node9
node9.next = node6


let hasCycle = function (head) {
  if (!head || !head.next) {
    return false
  }
  let fast = head.next.next,
    slow = head.next
  let i = 0
  while (fast !== slow) {
    if (!fast || !fast.next) {
      return false
    }
    fast = fast.next.next
    slow = slow.next
    i++
  }
  return true
}

const hasCycle2 = (head) => {
  try {
    JSON.stringify(head)
    return false
  } catch (error) {
    console.log(error)
    return true
  }
}

const hasCycle3 = (head) => {
  let link = head
  while (link) {
    if (link.flag) return true
    link.flag = true
    link = link.next
  }
  return false
}

var a = hasCycle3(node1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants