You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

链表aux指针最小修改:使所有节点可通过aux指针访问尾节点

解决方案:用最少的aux指针修改,让所有节点都能访问到链表尾

Great question! Let's walk through how to solve this problem with the absolute minimum number of aux pointer changes, while making sure every node can reach the tail via aux jumps.

Step 1: Find the tail node first

First up, we need to locate the tail of the linked list (the node where next is NULL, since it's the end of the single linked list). We can do this by traversing the list once using the next pointers—no modifications needed here, just a quick O(n) scan. While we're at it, it's helpful to collect all nodes into an array so we can easily work backwards later (since single linked lists don't let us traverse backwards directly).

Step 2: Build the minimal jump chain

Our goal isn't to make every node point directly to the tail (that would be O(n) changes in the worst case, which is unnecessary). Instead, we just need to ensure there's a path of aux jumps from every node to the tail. Here's the optimal strategy:

  1. Secure the tail first: Make sure the tail's aux points to itself. If it doesn't already, this is 1 quick modification. This prevents infinite loops when we jump to the tail, and gives us a solid starting point for our reachable set.
  2. Work backwards to cover all nodes: Starting from the second-to-last node and moving left to the head:
    • For each node, check if it can already reach the tail via its current aux pointer (we need to watch out for loops here—so track visited nodes to avoid infinite checks).
    • If it can't reach the tail, set its aux to point to the next node in the list (since we've already processed that next node, we know it can reach the tail). This one modification instantly makes the current node able to reach the tail (via the next node's aux path).

This way, we only modify the nodes that actually need it—no wasted changes. If a node's existing aux already leads to the tail, we leave it alone.

Code Example (C)

Here's a concrete implementation that follows this logic:

#include <stdio.h>
#include <stdlib.h>

struct Node {
    struct Node *next;
    struct Node *aux;
};

// Collect all nodes into an array and count them
struct Node** collectAllNodes(struct Node *head, int *nodeCount) {
    *nodeCount = 0;
    struct Node *current = head;
    // First pass to count nodes
    while (current != NULL) {
        (*nodeCount)++;
        current = current->next;
    }
    // Allocate array to store nodes
    struct Node** nodes = (struct Node**)malloc(*nodeCount * sizeof(struct Node*));
    current = head;
    int i = 0;
    while (current != NULL) {
        nodes[i++] = current;
        current = current->next;
    }
    return nodes;
}

// Check if a node can reach the tail via aux jumps (avoids loops)
int canReachTail(struct Node *node, struct Node *tail) {
    struct Node *current = node;
    struct Node** visited = NULL;
    int visitedCount = 0;

    while (current != NULL) {
        if (current == tail) {
            free(visited);
            return 1;
        }
        // Check if we've looped back to a node we already visited
        int loopDetected = 0;
        for (int i = 0; i < visitedCount; i++) {
            if (visited[i] == current) {
                loopDetected = 1;
                break;
            }
        }
        if (loopDetected) {
            free(visited);
            return 0;
        }
        // Track visited nodes to prevent loops
        visited = (struct Node**)realloc(visited, (visitedCount + 1) * sizeof(struct Node*));
        visited[visitedCount++] = current;
        current = current->aux;
    }
    free(visited);
    return 0;
}

// Modify aux pointers with minimal changes
void setupAuxForTailAccess(struct Node *head) {
    if (head == NULL) return;

    int nodeCount;
    struct Node** nodes = collectAllNodes(head, &nodeCount);
    struct Node *tail = nodes[nodeCount - 1];
    int modifyCount = 0;

    // Ensure tail points to itself
    if (tail->aux != tail) {
        tail->aux = tail;
        modifyCount++;
    }

    // Process nodes from second-to-last to head
    for (int i = nodeCount - 2; i >= 0; i--) {
        struct Node *current = nodes[i];
        if (!canReachTail(current, tail)) {
            // Point to next node (already can reach tail)
            current->aux = nodes[i + 1];
            modifyCount++;
        }
    }

    printf("Done! Modified %d aux pointers total.\n", modifyCount);
    free(nodes);
}

// Test case
int main() {
    // Create a linked list: 1 -> 2 -> 3 -> 4
    struct Node *node1 = (struct Node*)malloc(sizeof(struct Node));
    struct Node *node2 = (struct Node*)malloc(sizeof(struct Node));
    struct Node *node3 = (struct Node*)malloc(sizeof(struct Node));
    struct Node *node4 = (struct Node*)malloc(sizeof(struct Node));

    node1->next = node2; node1->aux = NULL;
    node2->next = node3; node2->aux = node1;
    node3->next = node4; node3->aux = NULL;
    node4->next = NULL; node4->aux = node2;

    setupAuxForTailAccess(node1);

    // Verify all nodes can reach the tail
    printf("Node 1 can reach tail? %d\n", canReachTail(node1, node4));
    printf("Node 2 can reach tail? %d\n", canReachTail(node2, node4));
    printf("Node 3 can reach tail? %d\n", canReachTail(node3, node4));
    printf("Node 4 can reach tail? %d\n", canReachTail(node4, node4));

    // Clean up memory
    free(node1); free(node2); free(node3); free(node4);
    return 0;
}

Why this is optimal

  • We only modify nodes that can't already reach the tail—no unnecessary changes.
  • By working backwards, we ensure that every node we modify points to a node that's already confirmed to reach the tail, so one change is enough to fix that node.
  • In the best case (all nodes already can reach the tail), we only make 0 or 1 change (if the tail didn't point to itself). In the worst case, we make n changes—but that's unavoidable, since every node needs a path to the tail.

Quick optimization tip

The canReachTail function uses a linear scan to check for loops, which can be slow for large lists. To speed this up, you could add a temporary boolean flag to the Node struct (if allowed) to mark nodes that can reach the tail, or use a hash table to track reachable nodes for O(1) lookups.


内容的提问来源于stack exchange,提问作者Yogesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:33:37