LeetCodeの連結リスト問題解法:ノード交換、削除、交差検出、循環検出

ノードのペア交換(問題24)

連結リストの隣接ノードを交換する実装例。ダミーノードを使用し、3つのポインタで前後関係を管理します。

class Solution {
public:
    ListNode* swapNodePairs(ListNode* head) {
        ListNode dummy(0);
        dummy.next = head;
        ListNode* current = &dummy;
        
        while (current->next && current->next->next) {
            ListNode* first = current->next;
            ListNode* second = first->next;
            
            first->next = second->next;
            second->next = first;
            current->next = second;
            
            current = first;
        }
        return dummy.next;
    }
};

末尾からN番目のノード削除(問題19)

リスト長を計算後、削除位置まで移動してノードを削除します。

class Solution {
public:
    ListNode* removeFromEnd(ListNode* head, int n) {
        ListNode dummy(0);
        dummy.next = head;
        ListNode* fast = &dummy;
        ListNode* slow = &dummy;
        
        for (int i = 0; i <= n; ++i) {
            fast = fast->next;
        }
        
        while (fast) {
            fast = fast->next;
            slow = slow->next;
        }
        
        ListNode* temp = slow->next;
        slow->next = temp->next;
        delete temp;
        
        return dummy.next;
    }
};

リスト交差検出(面接問題02.07)

2つのリストの長さ差を調整後、同時に走査して交差ノードを検出します。

class Solution {
public:
    ListNode* findIntersection(ListNode* headA, ListNode* headB) {
        int lenA = getLength(headA);
        int lenB = getLength(headB);
        
        while (lenA > lenB) {
            headA = headA->next;
            lenA--;
        }
        
        while (lenB > lenA) {
            headB = headB->next;
            lenB--;
        }
        
        while (headA != headB) {
            headA = headA->next;
            headB = headB->next;
        }
        
        return headA;
    }
    
private:
    int getLength(ListNode* node) {
        int length = 0;
        while (node) {
            length++;
            node = node->next;
        }
        return length;
    }
};

循環リスト検出(問題142)

フロイドの循環検出アルゴリズムを使用し、循環開始点を特定します。

class Solution {
public:
    ListNode* detectCycleStart(ListNode* head) {
        ListNode* slow = head;
        ListNode* fast = head;
        
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            
            if (slow == fast) {
                ListNode* finder = head;
                while (finder != slow) {
                    finder = finder->next;
                    slow = slow->next;
                }
                return finder;
            }
        }
        return nullptr;
    }
};

タグ: 連結リスト アルゴリズム LeetCode C++ ポインタ操作

7月10日 22:22 投稿