การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร
ตรวจจับเส้นเชื่อมที่ทำให้เกิดวงจรในกราฟไม่มีทิศทางด้วยการรวมแต่ละเส้นเชื่อม และตรวจสอบว่าโหนดสองตัวเชื่อมโยงกันอยู่แล้วหรือไม่
การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร เป็นบทเรียน Coding Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Coding Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
เส้นเชื่อมเกินคืออะไร
ปัญหา เส้นเชื่อมเกิน (LeetCode 684) ให้ต้นไม้ที่มีโหนด n โหนดและเส้นเชื่อมเกินมาอีกหนึ่งเส้น ซึ่งทำให้เกิดวัฏจักรเพียงหนึ่งวัฏจักร หน้าที่ของคุณคือค้นหาเส้นเชื่อมที่เมื่อลบออกแล้วจะทำให้ต้นไม้กลับมาเป็นต้นไม้ที่ถูกต้อง หากมีคำตอบหลายรายการ ให้ส่งคืนรายการสุดท้ายในรายการข้อมูลเข้า
ต้นไม้ที่มีโหนด n โหนดจะมีเส้นเชื่อมทั้งหมด n-1 เส้น เชื่อมต่อถึงกัน และไม่มีวัฏจักร การเพิ่มเส้นเชื่อมอีกหนึ่งเส้นจะสร้างวัฏจักรขึ้นมาเพียงหนึ่งวัฏจักร เส้นเชื่อมที่เพิ่มเข้ามา (เส้นเชื่อมเกิน) จะเชื่อมโหนดสองโหนดที่อยู่ในองค์ประกอบเดียวกันอยู่แล้ว ซึ่งเป็นสถานการณ์คลาสสิกสำหรับการตรวจจับวัฏจักรด้วย DSU
# Example
# n=5, edges = [[1,2],[1,3],[2,3],[2,4],[3,5]]
# Adding edge [2,3] creates cycle 1-2-3-1
# So [2,3] is the redundant connection
# Key insight: process edges one by one with DSU
# The FIRST edge where both endpoints are already connected is the redundant one
print('Tree property: n nodes, n-1 edges, no cycles')
print('Adding 1 edge: n nodes, n edges, exactly 1 cycle')
print('DSU approach: find the edge that connects already-connected nodes')การตรวจจับวัฏจักรด้วย DSU
DSU ตรวจจับวัฏจักรได้โดยธรรมชาติ: ก่อนเพิ่มเส้นเชื่อม (u, v) ให้ตรวจสอบว่า find(u) == find(v) หรือไม่ หากทั้งสองโหนดมีรากเดียวกัน แสดงว่าเชื่อมต่อกันอยู่แล้ว — การเพิ่มเส้นเชื่อมนี้จะสร้างวัฏจักร เส้นเชื่อมนี้คือ เส้นเชื่อมเกิน
วิธีนี้ใช้ได้กับกราฟไม่มีทิศทาง สำหรับเส้นเชื่อมแต่ละเส้น เราอาจ union องค์ประกอบทั้งสองได้สำเร็จ (ยังไม่เกิดวัฏจักร) หรือตรวจพบว่าปลายทั้งสองอยู่ในองค์ประกอบเดียวกันอยู่แล้ว (พบวัฏจักร) ความซับซ้อนด้านเวลาคือ O(n × alpha(n)) ซึ่งเกือบเท่ากับ O(n)
def find_redundant_connection(edges):
n = len(edges)
parent = list(range(n + 1)) # 1-indexed
rank = [0] * (n + 1)
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
px, py = find(x), find(y)
if px == py:
return False # same component => cycle found
if rank[px] < rank[py]: px, py = py, px
parent[py] = px
if rank[px] == rank[py]: rank[px] += 1
return True
for u, v in edges:
if not union(u, v):
return [u, v] # this edge creates the cycle
edges = [[1,2],[1,3],[2,3],[2,4],[3,5]]
print(find_redundant_connection(edges)) # [2, 3]การติดตามการทำงานของอัลกอริทึม
ลองติดตาม [[1,2],[1,3],[2,3]] ทีละขั้นตอน ในตอนเริ่มต้น แต่ละโหนดเป็นองค์ประกอบของตัวเอง: {1}, {2}, {3}
- เส้นเชื่อม [1,2]: find(1)=1, find(2)=2, แตกต่างกัน — union โหนดทั้งสอง องค์ประกอบ: {1,2}, {3}
- เส้นเชื่อม [1,3]: find(1)=ราก, find(3)=3, แตกต่างกัน — union โหนดทั้งสอง องค์ประกอบ: {1,2,3}
- เส้นเชื่อม [2,3]: find(2)=ราก, find(3)=ราก — รากเดียวกัน! ตรวจพบวัฏจักร ส่งคืน [2,3]
อัลกอริทึมประมวลผลเส้นเชื่อมตามลำดับและส่งคืนเส้นเชื่อมแรกที่ทำให้เกิดวัฏจักร เนื่องจากปัญหานี้รับประกันว่ามีเส้นเชื่อมเกินเพียงหนึ่งเส้น เส้นเชื่อมนี้จึงเป็นเส้นเชื่อมเกินที่ถูกต้องเสมอ
def find_redundant_trace(edges):
parent = list(range(len(edges) + 1))
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
for u, v in edges:
pu, pv = find(u), find(v)
print(f'Edge ({u},{v}): find({u})={pu}, find({v})={pv}', end=' => ')
if pu == pv:
print('CYCLE DETECTED!')
return [u, v]
parent[pv] = pu
print('merged')
return []
result = find_redundant_trace([[1,2],[1,3],[2,3]])
print('Redundant edge:', result)การตรวจจับวัฏจักรในกราฟไม่มีทิศทางด้วย DFS
ทางเลือกอื่นนอกเหนือจาก DSU สำหรับตรวจจับวัฏจักรในกราฟไม่มีทิศทางคือ DFS พร้อมการติดตามโหนดแม่ ระหว่างทำ DFS หากเราไปถึงโหนดที่เคยเยี่ยมชมแล้วและโหนดนั้นไม่ใช่โหนดแม่โดยตรงของโหนดปัจจุบัน แสดงว่าเราพบเส้นเชื่อมย้อนกลับ ซึ่งบ่งชี้ว่ามีวัฏจักร
อย่างไรก็ตาม วิธี DFS ต้องใช้เวลา O(V + E) และบอกได้ว่ามีวัฏจักรหรือไม่ แต่ไม่สามารถระบุได้ง่ายว่าเส้นเชื่อมใดเป็นเส้นเชื่อมเกิน DSU จึงเหมาะกว่าสำหรับปัญหาที่ขอให้ระบุเส้นเชื่อมเกินโดยเฉพาะ เพราะเราจะพบเส้นเชื่อมนั้นโดยธรรมชาติเมื่อการ union ล้มเหลว
from collections import defaultdict
def has_cycle_dfs(n, edges):
graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
graph[v].append(u)
visited = set()
def dfs(node, parent):
visited.add(node)
for nb in graph[node]:
if nb == parent:
continue # skip the edge we came from
if nb in visited:
return True # back edge => cycle
if dfs(nb, node):
return True
return False
for node in range(1, n + 1):
if node not in visited:
if dfs(node, -1):
return True
return False
print(has_cycle_dfs(3, [[1,2],[1,3],[2,3]])) # True
print(has_cycle_dfs(3, [[1,2],[1,3]])) # Falseการตรวจจับวัฏจักรในกราฟมีทิศทาง
สำหรับ กราฟมีทิศทาง การตรวจจับวัฏจักรด้วย DSU ไม่สามารถใช้ได้โดยตรง เนื่องจากเส้นเชื่อมมีทิศทาง ให้ใช้ DFS พร้อมการทำเครื่องหมายสามสี แทน ได้แก่ สีขาว (ยังไม่เยี่ยมชม) สีเทา (อยู่ในเส้นทาง DFS ปัจจุบัน) และสีดำ (ประมวลผลเสร็จสมบูรณ์) เส้นเชื่อมย้อนกลับไปยังโหนดสีเทาบ่งชี้ว่ามีวัฏจักร
ในกราฟไม่มีทิศทาง เส้นเชื่อมย้อนกลับใด ๆ ก็หมายถึงมีวัฏจักร แต่ในกราฟมีทิศทาง เส้นเชื่อมข้ามไปยังโหนดสีดำไม่ใช่วัฏจักร — มีเพียงเส้นเชื่อมย้อนกลับไปยังโหนดสีเทาเท่านั้นที่เป็นวัฏจักร ความแตกต่างนี้สำคัญมากและมีการทดสอบในปัญหาจัดตารางรายวิชา
def has_cycle_directed(n, edges):
graph = defaultdict(list)
for u, v in edges:
graph[u].append(v)
# 0=white(unvisited), 1=grey(in stack), 2=black(done)
color = [0] * (n + 1)
def dfs(node):
color[node] = 1 # grey: currently visiting
for nb in graph[node]:
if color[nb] == 1:
return True # back edge to grey node => cycle
if color[nb] == 0:
if dfs(nb):
return True
color[node] = 2 # black: fully processed
return False
for node in range(1, n + 1):
if color[node] == 0:
if dfs(node):
return True
return False
from collections import defaultdict
print(has_cycle_directed(3, [[1,2],[2,3],[3,1]])) # True: 1->2->3->1
print(has_cycle_directed(3, [[1,2],[1,3],[2,3]])) # Falseเส้นเชื่อมเกิน II: รูปแบบกราฟมีทิศทาง
LeetCode 685 ขยายปัญหาไปสู่กราฟมีทิศทางที่แต่ละโหนดมีโหนดแม่เพียงหนึ่งโหนด (เป็นต้นไม้ที่มีรากและมีเส้นเชื่อมเกินอีกหนึ่งเส้น) มีสองกรณีที่อาจเกิดขึ้น ได้แก่ โหนดหนึ่งมีโหนดแม่สองโหนด (ดีกรีขาเข้าเป็น 2) หรือมีวัฏจักรโดยไม่มีโหนดใดมีโหนดแม่สองโหนด
วิธีแก้จะตรวจหาโหนดที่มีดีกรีขาเข้าเป็น 2 ก่อน หากพบ เส้นเชื่อมขาเข้าเส้นใดเส้นหนึ่งจากสองเส้นนั้นต้องเป็นคำตอบ จากนั้นใช้การตรวจจับวัฏจักรด้วย DSU เพื่อพิจารณาว่าควรลบเส้นเชื่อมตัวเลือกใด วิธีแบบสองระยะนี้จัดการได้ถูกต้องในทุกกรณี
def find_redundant_directed(edges):
n = len(edges)
parent_map = {} # node -> its parent in the input
candidate1 = candidate2 = None
for u, v in edges:
if v in parent_map: # v already has a parent
candidate1 = [parent_map[v], v] # earlier edge
candidate2 = [u, v] # later edge
else:
parent_map[v] = u
# DSU cycle detection, skipping candidate2 if it exists
dsu = list(range(n + 1))
def find(x):
while dsu[x] != x: dsu[x] = dsu[dsu[x]]; x = dsu[x]
return x
def union(x, y):
px, py = find(x), find(y)
if px == py: return False
dsu[px] = py; return True
for u, v in edges:
if candidate2 and [u, v] == candidate2: continue # skip candidate2
if not union(u, v): # cycle found without candidate2
return candidate1 if candidate1 else [u, v]
return candidate2 # no cycle when excluding candidate2 => candidate2 is redundant
print(find_redundant_directed([[1,2],[1,3],[2,3]])) # [2,3]
print(find_redundant_directed([[1,2],[2,3],[3,4],[4,1],[1,5]])) # [4,1]การตรวจสอบความถูกต้องของกราฟหลังลบเส้นเชื่อม
หลังจากระบุเส้นเชื่อมเกินแล้ว เราสามารถตรวจสอบผลลัพธ์ได้โดยดูว่าการลบเส้นเชื่อมนั้นทำให้เหลือต้นไม้ที่ถูกต้องหรือไม่: มีเส้นเชื่อม n-1 เส้นพอดี โหนดทั้งหมดเชื่อมต่อกัน และไม่มีวัฏจักร สำหรับปัญหาสัมภาษณ์นี้ DSU รับประกันคุณสมบัติดังกล่าวโดยธรรมชาติ — หากเราส่งคืนเส้นเชื่อมที่ทำให้การ union ล้มเหลว เมื่อลบเส้นเชื่อมนั้น เราจะเหลือเส้นเชื่อม n-1 เส้นที่ union สำเร็จพอดี และเส้นเชื่อมเหล่านั้นจะประกอบกันเป็นต้นไม้ทอดข้าม
การรับประกันนี้เป็นเหตุผลที่ DSU เหมาะสมกับปัญหานี้มาก: การ union ที่สำเร็จจะสร้างต้นไม้ทีละขั้น และการ union ที่ล้มเหลวจะระบุเส้นเชื่อมหนึ่งเส้นที่ไม่ควรอยู่ในต้นไม้
def verify_tree(n, edges, removed_edge):
parent = list(range(n + 1))
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]]
x = parent[x]
return x
components = n
for u, v in edges:
if [u, v] == removed_edge:
continue # skip the removed edge
pu, pv = find(u), find(v)
if pu == pv:
print('CYCLE DETECTED after removal! Wrong answer.')
return False
parent[pv] = pu
components -= 1
if components != 1:
print(f'Graph not connected ({components} components). Wrong answer.')
return False
print('Valid tree after removing edge:', removed_edge)
return True
edges = [[1,2],[1,3],[2,3]]
verify_tree(3, edges, [2,3])
verify_tree(3, edges, [1,2]) # wrong removalการวิเคราะห์ความซับซ้อนด้านเวลาและพื้นที่
วิธีแก้ปัญหาเส้นเชื่อมเกินด้วย DSU จะประมวลผลเส้นเชื่อมทั้ง n เส้นครั้งละหนึ่งครั้ง และการดำเนินการ union/find แต่ละครั้งใช้เวลา O(alpha(n)) แบบเฉลี่ยสะสม เวลารวมคือ O(n × alpha(n)) ซึ่งในทางปฏิบัติเท่ากับ O(n)
ความซับซ้อนด้านพื้นที่คือ O(n) สำหรับอาร์เรย์โหนดแม่และอันดับ วิธีนี้เหมาะสมที่สุดแล้ว — อย่างน้อยคุณต้องอ่านเส้นเชื่อมทั้ง n เส้นและจัดเก็บสถานะบางส่วนสำหรับแต่ละโหนด ลองเปรียบเทียบกับวิธีพื้นฐานที่เรียกใช้ DFS หลังการเพิ่มเส้นเชื่อมแต่ละเส้น: ใช้เวลา O(n²) และพื้นที่ O(n + E)
# Summary of complexities
complexity = {
'Naive (DFS after each edge)': {'time': 'O(n^2)', 'space': 'O(n)'},
'DSU (path compression + rank)': {'time': 'O(n * alpha(n))', 'space': 'O(n)'},
'Sorting + DSU (Kruskal style)': {'time': 'O(n log n)', 'space': 'O(n)'},
}
for approach, costs in complexity.items():
print(f'{approach}:')
print(f' Time: {costs["time"]}')
print(f' Space: {costs["space"]}')
print()
print('alpha(n) <= 4 for all practical n, so DSU is effectively O(n).')กรณีขอบ: เส้นเชื่อมวนกลับหาตัวเอง
เส้นเชื่อมวนกลับหาตัวเอง [u, u] จะสร้างวัฏจักรทันที เนื่องจากปลายทั้งสองคือโหนดเดียวกัน ใน DSU find(u) == find(u) เป็นจริงเสมอ ดังนั้นการ union จึงล้มเหลวทันที และ [u, u] จะถูกส่งคืนเป็นเส้นเชื่อมเกิน
เงื่อนไขของปัญหาส่วนใหญ่รับประกันว่าจะไม่มีเส้นเชื่อมวนกลับหาตัวเอง แต่โค้ดที่รัดกุมควรรองรับกรณีนี้ การทำงานของ DSU รองรับกรณีนี้ได้โดยธรรมชาติโดยไม่ต้องมีกรณีพิเศษ — การตรวจสอบวัฏจักร if find(u) == find(v) จะตรวจพบก่อนที่จะพยายามทำ union เสมอ โปรดตรวจสอบด้วยข้อมูลเข้ากรณีขอบ เช่น เส้นเชื่อมวนกลับหาตัวเองในกราฟที่มีโหนดเดียวและข้อมูลเข้าขนาดต่ำสุด
def find_redundant_robust(edges):
n = len(edges)
parent = list(range(n + 1))
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
for u, v in edges:
pu, pv = find(u), find(v)
if pu == pv:
return [u, v] # handles self-loops too: u==v => pu==pv always
parent[pv] = pu
return []
# Self-loop test
print(find_redundant_robust([[1,2],[2,2]])) # [2,2] self-loop
# Minimum tree test
print(find_redundant_robust([[1,2],[2,3],[1,3]])) # [1,3]
# Standard test
print(find_redundant_robust([[1,2],[1,3],[2,3],[2,4],[3,5]])) # [2,3]การประยุกต์ใช้การตรวจจับวัฏจักรกับอัลกอริทึมต่าง ๆ
มีอัลกอริทึมหลายแบบที่ใช้ตรวจจับวัฏจักร โดยแต่ละแบบเหมาะกับสถานการณ์แตกต่างกัน:
- DSU: กราฟไม่มีทิศทาง เส้นเชื่อมเข้ามาแบบออนไลน์ ใช้เวลา O(alpha(n)) ต่อเส้นเชื่อม — เหมาะที่สุดสำหรับการนับหรือค้นหาเส้นเชื่อมเกิน
- DFS พร้อมการติดตามโหนดแม่: กราฟไม่มีทิศทาง รู้เส้นเชื่อมทั้งหมดตั้งแต่ต้น ใช้เวลา O(V+E) — เหมาะที่สุดเมื่อต้องการเส้นทางของวัฏจักร
- DFS แบบสามสี: กราฟมีทิศทาง ใช้ตรวจหาเส้นเชื่อมย้อนกลับ ใช้เวลา O(V+E) — เหมาะที่สุดสำหรับปัญหาจัดตารางรายวิชาและการเรียงลำดับเชิงทอพอโลยี
- การเรียงลำดับเชิงทอพอโลยี (ของ Kahn): กราฟมีทิศทาง ตรวจจับวัฏจักรผ่านโหนดที่มีดีกรีขาเข้าไม่เป็นศูนย์ซึ่งเหลืออยู่ — เหมาะที่สุดเมื่อต้องการการจัดลำดับด้วย
# When to use which cycle-detection method:
# Problem type => preferred algorithm
problems = [
('Redundant Connection (undirected)', 'DSU'),
('Course Schedule (directed)', 'DFS three-color or Kahn topological sort'),
('Detect cycle in undirected graph', 'DFS with parent tracking or DSU'),
('Find cycle members in directed graph', 'DFS three-color + backtrack'),
('Online graph edges with cycle check', 'DSU'),
('Minimum spanning tree validity', 'DSU (Kruskal)'),
]
for problem, solution in problems:
print(f'{problem}\n => {solution}\n')วิธีแก้ปัญหาฉบับสมบูรณ์พร้อมกรณีขอบ
นี่คือวิธีแก้ปัญหาเส้นเชื่อมเกินระดับใช้งานจริงที่จัดการกรณีขอบทั้งหมด ได้แก่ โหนดที่เริ่มนับดัชนีจาก 1 เส้นเชื่อมเกินเพียงหนึ่งเส้น และการรับประกันว่าการลบเส้นเชื่อมนั้นจะเหลือต้นไม้ที่ถูกต้อง วิธีนี้ใช้ DSU ที่มีประสิทธิภาพสูงสุด โดยใช้การลดครึ่งเส้นทางและการ union ตามอันดับ
หลังจากส่งคำตอบแล้ว ลองทำคำถามต่อยอด: จะเกิดอะไรขึ้นหากกราฟอาจมีเส้นเชื่อมเกินหลายเส้น คุณจะต้องติดตามเส้นเชื่อมทั้งหมดที่ทำให้เกิดวัฏจักรและส่งคืนเส้นสุดท้ายในรายการข้อมูลเข้า — กลยุทธ์แบบละโมบเดิมยังคงใช้ได้ เพราะ DSU ประมวลผลเส้นเชื่อมตามลำดับ
def find_redundant_connection(edges):
n = len(edges)
parent = list(range(n + 1))
rank = [0] * (n + 1)
def find(x):
while parent[x] != x:
parent[x] = parent[parent[x]] # path halving
x = parent[x]
return x
def union(x, y):
px, py = find(x), find(y)
if px == py:
return False
if rank[px] < rank[py]:
px, py = py, px
parent[py] = px
if rank[px] == rank[py]:
rank[px] += 1
return True
for u, v in edges:
if not union(u, v):
return [u, v]
return [] # should never reach here given valid input
test_cases = [
[[1,2],[1,3],[2,3]],
[[1,2],[2,3],[3,4],[1,4],[1,5]],
[[1,2],[1,3],[2,3],[2,4],[3,5]],
]
for tc in test_cases:
print(find_redundant_connection(tc))ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับแนวคิดโครงสร้างข้อมูล & อัลกอริทึม — การเตรียมตัวสัมภาษณ์การเขียนโปรแกรมจากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า เส้นเชื่อมเกินคือเส้นเชื่อมที่เชื่อมโหนดสองโหนดซึ่งเชื่อมต่อกันอยู่แล้วในกราฟไม่มีทิศทาง DSU ตรวจจับกรณีนี้โดยตรวจสอบ find(u) == find(v) ก่อนทำ union แล้วส่งคืนเส้นเชื่อมนั้น และ กราฟมีทิศทางต้องใช้ DFS แบบสามสีหรืออัลกอริทึมของ Kahn แทน DSU เพื่อตรวจจับวัฏจักร บทถัดไป เราจะใช้ DSU กับปัญหาการผสานบัญชี ซึ่งมีอีเมลเป็นโหนด และอีเมลที่ใช้ร่วมกันระหว่างบัญชีจะทำให้เกิดการ union
คำถามที่พบบ่อย
บทเรียน “การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Coding Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร”
ตรวจจับเส้นเชื่อมที่ทำให้เกิดวงจรในกราฟไม่มีทิศทางด้วยการรวมแต่ละเส้นเชื่อม และตรวจสอบว่าโหนดสองตัวเชื่อมโยงกันอยู่แล้วหรือไม่ คุณปฏิบัติ Coding Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Coding Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Coding Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Coding Interview Prep นี้ได้ไหม
ได้ บทเรียน Coding Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- DSU กับการบีบอัดเส้นทาง
- การรวมตามอันดับและขอบเขตอินเวอร์สแอกเคอร์มันน์
- การเชื่อมโยงเกินจำเป็นและการตรวจจับวงจร
- การรวมบัญชีและองค์ประกอบเชื่อมโยง