37
37
38
38
<!-- 这里可写通用的实现逻辑 -->
39
39
40
- 设 ` f(n, m) ` 表示从 n 个数中每次删除第 m 个,最后剩下的数字。
40
+ ** 方法一:数学 + 递归(迭代) **
41
41
42
- 第一次删除第 m 个,剩下 ` n-1 ` 个数,那么 ` x = f(n - 1 , m)` 就表示从 n-1 个数中每次删除第 m 个,最后剩下的数字 。
42
+ 我们不妨设 $ f(n, m)$ 表示从 $n$ 个数中每次删除第 $m$ 个,最后剩下的是第几个数字 。
43
43
44
- 我们求得 x 之后,便可以知道, ` f(n, m) ` 应该是从 ` m % n ` 开始数的第 x 个元素,即 ` f(n, m) = ((m % n) + x) % n ` 。
44
+ 我们第一次删除了第 $m$ 个数字,剩下 $n-1$ 个数,那么 $x= f(n - 1 , m)$ 就表示从剩下的 $n-1$ 个数中,每次删除第 $m$ 个,最后剩下的是第几个数字 。
45
45
46
- 当 n 为 1 时,最后留下的数字序号一定为 0。
46
+ 我们求得 $x$ 之后,便可以知道 $f(n, m)$ 应该是从 $m \% n$ 开始数的第 $x$ 个元素,即 $f(n, m) = (m \% n + x) \% n$。
47
+
48
+ 当 $n$ 为 $1$ 时,最后留下的数字序号一定为 $0$。
47
49
48
50
递归求解即可,也可以改成迭代。
49
51
52
+ 时间复杂度 $O(n)$,递归的空间复杂度 $O(n)$,迭代的空间复杂度 $O(1)$。
53
+
50
54
<!-- tabs:start -->
51
55
52
56
### ** Python3**
53
57
54
58
<!-- 这里可写当前语言的特殊实现逻辑 -->
55
59
56
- 递归版本:
57
-
58
60
``` python
59
61
class Solution :
60
62
def lastRemaining (self , n : int , m : int ) -> int :
@@ -67,8 +69,6 @@ class Solution:
67
69
return f(n, m)
68
70
```
69
71
70
- 迭代版本:
71
-
72
72
``` python
73
73
class Solution :
74
74
def lastRemaining (self , n : int , m : int ) -> int :
@@ -82,6 +82,22 @@ class Solution:
82
82
83
83
<!-- 这里可写当前语言的特殊实现逻辑 -->
84
84
85
+ ``` java
86
+ class Solution {
87
+ public int lastRemaining (int n , int m ) {
88
+ return f(n, m);
89
+ }
90
+
91
+ private int f (int n , int m ) {
92
+ if (n == 1 ) {
93
+ return 0 ;
94
+ }
95
+ int x = f(n - 1 , m);
96
+ return (m + x) % n;
97
+ }
98
+ }
99
+ ```
100
+
85
101
``` java
86
102
class Solution {
87
103
public int lastRemaining (int n , int m ) {
@@ -94,26 +110,54 @@ class Solution {
94
110
}
95
111
```
96
112
97
- ### ** JavaScript **
113
+ ### ** C++ **
98
114
99
- ``` js
100
- /**
101
- * @param {number} n
102
- * @param {number} m
103
- * @return {number}
104
- */
105
- var lastRemaining = function (n , m ) {
106
- // 约瑟夫环
107
- let res = 0 ;
108
- for (let i = 1 ; i <= n; i++ ) {
109
- res = (res + m) % i;
115
+ ``` cpp
116
+ class Solution {
117
+ public:
118
+ int lastRemaining(int n, int m) {
119
+ return f(n, m);
120
+ }
121
+
122
+ int f(int n, int m) {
123
+ if (n == 1) {
124
+ return 0;
125
+ }
126
+ int x = f(n - 1 , m);
127
+ return (m + x) % n;
128
+ }
129
+ };
130
+ ```
131
+
132
+ ``` cpp
133
+ class Solution {
134
+ public:
135
+ int lastRemaining(int n, int m) {
136
+ int f = 0;
137
+ for (int i = 2; i <= n; ++i) {
138
+ f = (f + m) % i;
139
+ }
140
+ return f;
110
141
}
111
- return res;
112
142
};
113
143
```
114
144
115
145
### **Go**
116
146
147
+ ```go
148
+ func lastRemaining(n int, m int) int {
149
+ var f func(n, m int) int
150
+ f = func(n, m int) int {
151
+ if n == 1 {
152
+ return 0
153
+ }
154
+ x := f(n-1, m)
155
+ return (m + x) % n
156
+ }
157
+ return f(n, m)
158
+ }
159
+ ```
160
+
117
161
``` go
118
162
func lastRemaining (n int , m int ) int {
119
163
f := 0
@@ -124,6 +168,23 @@ func lastRemaining(n int, m int) int {
124
168
}
125
169
```
126
170
171
+ ### ** JavaScript**
172
+
173
+ ``` js
174
+ /**
175
+ * @param {number} n
176
+ * @param {number} m
177
+ * @return {number}
178
+ */
179
+ var lastRemaining = function (n , m ) {
180
+ let f = 0 ;
181
+ for (let i = 2 ; i <= n; ++ i) {
182
+ f = (f + m) % i;
183
+ }
184
+ return f;
185
+ };
186
+ ```
187
+
127
188
### ** C#**
128
189
129
190
``` cs
0 commit comments