Reversing Linked Lists and Related Problems with Go Implementations
This article presents detailed explanations, algorithmic ideas, and complete Go code for reversing an entire singly linked list, reversing a sub‑list between positions m and n, finding the intersection node of two lists, detecting cycles, and partitioning a list around a pivot value.
This document covers several classic linked‑list problems from LeetCode, providing problem statements, algorithmic insights, and full Go implementations.
1. Reverse the entire linked list
Problem: Reverse a singly‑linked list. Example input 1→2→3→4→5→NULL yields 5→4→3→2→1→NULL. The solution can be iterative or recursive.
Algorithm idea: Use two pointers, pre (previous node) and next (temporary storage for the next node). Iterate through the list, re‑link each node to its predecessor in four steps: backup next node, reverse the link, move pre forward, and advance the current node.
type LikedList struct{
Val int
Next *LikedList
}
// Head insertion method to reverse a singly linked list
func reverseLikedList(head *LikedList) *LikedList {
if head == nil || head.Next == nil {
return head
}
var pre, next *LikedList
for head != nil {
next = head.Next // backup next node
head.Next = pre // reverse link
pre = head // move pre forward
head = next // advance current node
}
return pre // pre now points to the new head
}2. Reverse a sub‑list from position m to n
Problem: Given positions m and n (1 ≤ m ≤ n ≤ length), reverse the nodes between them in a single pass.
Algorithm idea: Record four critical nodes: the predecessor of m, the m‑th node, the n‑th node, and the successor of n. Move a pointer to the m‑th node, then iteratively reverse the next n‑m+1 nodes, finally reconnect the reversed segment with the surrounding parts.
/**
* Definition for singly‑linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseBetween(head *ListNode, m int, n int) *ListNode {
changeLen := n - m + 1
var pre *ListNode = nil
var result *ListNode = head
move := m - 1
for head != nil && move > 0 {
pre = head
head = head.Next
move--
}
var reversedListTail *ListNode = head
var reversedListHead *ListNode = nil
for head != nil && changeLen > 0 {
next := head.Next
head.Next = reversedListHead
reversedListHead = head
head = next
changeLen--
}
reversedListTail.Next = head
if pre != nil {
pre.Next = reversedListHead
} else {
result = reversedListHead
}
return result
}3. Find the intersection node of two singly linked lists
Problem: Return the first common node of two lists, or null if they do not intersect. The solution should run in O(n) time and O(1) extra space.
Algorithm idea: Compute the lengths of both lists, advance the head of the longer list by the length difference, then move both heads together until they meet or reach the end.
/**
* Definition for singly‑linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
var lenA, lenB int
lenA = getListLength(headA)
lenB = getListLength(headB)
if lenA > lenB {
headA = forwardDeltaLenNode(lenA, lenB, headA)
} else {
headB = forwardDeltaLenNode(lenB, lenA, headB)
}
for headA != nil && headB != nil {
if headA == headB {
return headA
}
headA = headA.Next
headB = headB.Next
}
return nil
}
func getListLength(head *ListNode) int {
var length int
for head != nil {
length++
head = head.Next
}
return length
}
func forwardDeltaLenNode(longLen, shortLen int, longList *ListNode) *ListNode {
delta := longLen - shortLen
for longList != nil && delta != 0 {
longList = longList.Next
delta--
}
return longList
}4. Detect a cycle in a linked list and locate its start and length
The article outlines the problem statement (detect whether a list contains a loop, and if so, return the entry node and the loop length) but does not provide concrete code; typical solutions use Floyd’s Tortoise‑and‑Hare algorithm.
5. Partition a linked list around a value x
Problem: Rearrange the list so that all nodes with values less than x appear before nodes with values greater than or equal to x, preserving the original relative order within each partition.
Algorithm idea: Create two dummy heads ( preHead and postHead) for the “less” and “greater/equal” partitions. Iterate through the original list, appending each node to the appropriate partition, then link the two partitions together.
/**
* Definition for singly‑linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func partition(head *ListNode, x int) *ListNode {
preHead := &ListNode{0, nil}
postHead := &ListNode{0, nil}
prePtr := preHead
postPtr := postHead
for head != nil {
if head.Val < x {
prePtr.Next = head
prePtr = head
} else {
postPtr.Next = head
postPtr = head
}
head = head.Next
}
prePtr.Next = postHead.Next
postPtr.Next = nil
return preHead.Next
}All the above solutions are written in Go and are intended for interview preparation on platforms such as LeetCode.
Source: goline.blog.csdn.net article (original Chinese content).
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
