// 循环链表节点 type LinkList struct { val int next *LinkList }
funclastRemaining(n int, m int)int { head, rear := buildLinkList(n) // 构建一个循环链表 // 下面开始模拟删除过程,删除n-1个元素 cur := head // 当前遍历元素 pre := rear // 当前遍历元素的前驱 for n > 1 { // 找到第m个节点 for i := 1; i < m; i++ { pre = cur cur = cur.next } // 删除第m个节点 pre.next = cur.next // 下一次从删除后的下一个数字开始计数 cur = pre.next n-- }
return cur.val }
// 根据0, 1, 2, ..., n-1构造一个循环链表,返回链表头和链表尾 funcbuildLinkList(n int)(*LinkList, *LinkList) { head := &LinkList{ val: 0 } // 指向循环链表头 rear := head // 指向循环链表的最后一个节点 for i := 1; i < n; i++ { newNode := &LinkList{ val: i } rear.next = newNode rear = newNode } // 最后一个节点连接到第一个节点,构成循环特性 rear.next = head
return head, rear }
数学推导
1 2 3 4 5 6 7 8 9
funclastRemaining(n int, m int)int { ans := 0// 最后一轮剩下的元素下标必然是0 // 从倒数第2轮开始反推 for i := 2; i <= n; i++ { ans = (ans + m) % i }