LeetCode騰訊50題-Day11-136/141/142
技術標籤:pythonLeetCode連結串列leetcodepython演算法資料結構
LeetCode50題(17天)-Day11
136 只出現一次的數字
- 題號:136
- 難度:簡單
- https://leetcode-cn.com/problems/single-number/
給定一個非空整數陣列,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素。
說明:
你的演算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?
示例 1:
輸入: [2,2,1]
輸出: 1
示例 2:
輸入: [4,1,2,1,2]
輸出: 4
實現
第一種:通過集合的方法
C# 語言
- 狀態:通過
- 16 / 16 個通過測試用例
- 執行用時: 136 ms, 在所有 C# 提交中擊敗了 98.86% 的使用者
- 記憶體消耗: 26.4 MB, 在所有 C# 提交中擊敗了 5.34% 的使用者
public class Solution
{
public int SingleNumber(int[] nums)
{
HashSet<int> h = new HashSet<int>();
for (int i = 0; i < nums.Length; i++)
{
if ( h.Contains(nums[i]))
{
h.Remove(nums[i]);
}
else
{
h.Add(nums[i]);
}
}
return h.ElementAt(0);
}
}
Python 語言
- 執行結果:通過
- 執行用時:60 ms, 在所有 Python3 提交中擊敗了 55.88% 的使用者
- 記憶體消耗:15.6 MB, 在所有 Python3 提交中擊敗了 5.26% 的使用者
class Solution:
def singleNumber(self, nums: List[int]) -> int:
h = set()
for num in nums:
if num in h:
h.remove(num)
else:
h.add(num)
return list(h)[0]
第二種:利用位運算的方法。
A: 00 00 11 00
B: 00 00 01 11
A^B: 00 00 10 11
B^A: 00 00 10 11
A^A: 00 00 00 00
A^0: 00 00 11 00
A^B^A: = A^A^B = B = 00 00 01 11
"異或"操作滿足交換律和結合律。
C# 實現
- 狀態:通過
- 16 / 16 個通過測試用例
- 執行用時: 144 ms, 在所有 C# 提交中擊敗了 91.76% 的使用者
- 記憶體消耗: 25.4 MB, 在所有 C# 提交中擊敗了 11.39% 的使用者
public class Solution
{
public int SingleNumber(int[] nums)
{
int result = 0;
for (int i = 0; i < nums.Length; i++)
{
result ^= nums[i];
}
return result;
}
}
Python 實現
- 執行結果:通過
- 執行用時:44 ms, 在所有 Python3 提交中擊敗了 84.17% 的使用者
- 記憶體消耗:15.3 MB, 在所有 Python3 提交中擊敗了 5.26% 的使用者
class Solution:
def singleNumber(self, nums: List[int]) -> int:
result = 0
for item in nums:
result ^= item
return result
141 環形連結串列
- 題號:141
- 難度:簡單
- https://leetcode-cn.com/problems/linked-list-cycle/
給定一個連結串列,判斷連結串列中是否有環。
為了表示給定連結串列中的環,我們使用整數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)(即,常量)記憶體解決此問題嗎?
實現
第一種:通過集合的方法
通過檢查一個結點此前是否被訪問過來判斷連結串列是否為環形連結串列。
C# 語言
- 狀態:通過
- 執行用時:112 ms, 在所有 C# 提交中擊敗了 84.04% 的使用者
- 記憶體消耗:26.5 MB, 在所有 C# 提交中擊敗了 100.00% 的使用者
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public bool HasCycle(ListNode head)
{
HashSet<ListNode> h = new HashSet<ListNode>();
ListNode temp = head;
while (temp != null)
{
if (h.Contains(temp))
return true;
h.Add(temp);
temp = temp.next;
}
return false;
}
}
Python 語言
- 執行結果:通過
- 執行用時:60 ms, 在所有 Python3 提交中擊敗了 64.49% 的使用者
- 記憶體消耗:17.3 MB, 在所有 Python3 提交中擊敗了 9.52% 的使用者
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
h = set()
temp = head
while temp is not None:
if temp in h:
return True
h.add(temp)
temp = temp.next
return False
第二種:利用雙指標的方式
通常情況下,判斷是否包含了重複的元素,我們使用Hash
的方式來做。對於單鏈表的這種場景,我們也可以使用雙指標的方式。
第一個指標 p1
每次移動兩個節點,第二個指標 p2
每次移動一個節點,如果該連結串列存在環的話,第一個指標一定會再次碰到第二個指標,反之,則不存在環。
比如:head = [1,2,3,4,5]
,奇數
p1:1 3 5 2 4 1
p2:1 2 3 4 5 1
比如:head = [1,2,3,4]
,偶數
p1:1 3 1 3 1
p2:1 2 3 4 1
C# 語言
- 狀態:通過
- 執行用時: 112 ms, 在所有 C# 提交中擊敗了 98.43% 的使用者
- 記憶體消耗: 24.9 MB, 在所有 C# 提交中擊敗了 5.13% 的使用者
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public bool HasCycle(ListNode head) {
ListNode p1 = head;
ListNode p2 = head;
while (p1 != null && p1.next != null)
{
p1 = p1.next.next;
p2 = p2.next;
if (p1 == p2)
return true;
}
return false;
}
}
Python 語言
- 執行結果:通過
- 執行用時:56 ms, 在所有 Python3 提交中擊敗了 60.97% 的使用者
- 記憶體消耗:16.6 MB, 在所有 Python3 提交中擊敗了 11.81% 的使用者
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
p1 = head
p2 = head
while p1 is not None and p1.next is not None:
p1 = p1.next.next
p2 = p2.next
if p1 == p2:
return True
return False
142 環形連結串列2
- 題號:142
- 難度:中等
- https://leetcode-cn.com/problems/linked-list-cycle-ii/
給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 null。
為了表示給定連結串列中的環,我們使用整數 pos 來表示連結串列尾連線到連結串列中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該連結串列中沒有環。
說明:不允許修改給定的連結串列。
示例 1:
輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1
解釋:連結串列中有一個環,其尾部連線到第二個節點。
示例 2:
輸入:head = [1,2], pos = 0
輸出:tail connects to node index 0
解釋:連結串列中有一個環,其尾部連線到第一個節點。
示例 3:
輸入:head = [1], pos = -1
輸出:no cycle
解釋:連結串列中沒有環。
進階:
你是否可以不用額外空間解決此題?
實現
第一種:利用暴力匹配的方式
- 狀態:通過
- 16 / 16 個通過測試用例
- 執行用時: 412 ms, 在所有 C# 提交中擊敗了 17.07% 的使用者
- 記憶體消耗: 24.8 MB, 在所有 C# 提交中擊敗了 10.00% 的使用者
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode DetectCycle(ListNode head)
{
if (head == null)
return null;
ListNode p1 = head;
int i = 0;
while (p1 != null)
{
p1 = p1.next;
i++;
ListNode p2 = head;
int j = 0;
while (j < i)
{
if (p2 == p1)
{
return p2;
}
p2 = p2.next;
j++;
}
}
return null;
}
}
第二種:通過集合的方法
C# 語言
- 狀態:通過
- 16 / 16 個通過測試用例
- 執行用時: 140 ms, 在所有 C# 提交中擊敗了 82.93% 的使用者
- 記憶體消耗: 26 MB, 在所有 C# 提交中擊敗了 5.00% 的使用者
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution
{
public ListNode DetectCycle(ListNode head)
{
HashSet<ListNode> h = new HashSet<ListNode>();
ListNode temp = head;
while (temp != null)
{
if (h.Contains(temp))
return temp;
h.Add(temp);
temp = temp.next;
}
return null;
}
}
Python 語言
- 執行結果:通過
- 執行用時:72 ms, 在所有 Python3 提交中擊敗了 36.52% 的使用者
- 記憶體消耗:17.2 MB, 在所有 Python3 提交中擊敗了 7.69% 的使用者
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
h = set()
temp = head
while temp is not None:
if temp in h:
return temp
h.add(temp)
temp = temp.next
return None