@@ -198,20 +198,138 @@ public int Sum_Solution(int n) {
198198[ 从 1 到 n 整数中 1 出现的次数] ( https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking )
199199
200200``` java
201+ public int NumberOf1Between1AndN_Solution(int n) {
202+ if (n< 1 ){
203+ return 0 ;
204+ }
205+
206+ int res= 0 ;
207+
208+ int base= 1 ;
209+ int round = n; // n 为原始数字
201210
211+ while (round> 0 ){
212+ int weight = round % 10 ;
213+ round /= 10 ;
214+ res += round* base;
215+ if (weight== 1 ){
216+ int formatter = n% base; // formatter 就是 weight 位的后一位
217+ res += formatter+ 1 ;
218+ }else if (weight> 1 ){
219+ res += base;
220+ }
221+ base*= 10 ;
222+ }
223+ return res;
224+ }
202225```
203226
204227> [ Leetcode : 233. Number of Digit One] ( https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython )
205228
229+ > [ 参考:从 1 到 n 整数中 1 出现的次数] ( https://blog.csdn.net/yi_Afly/article/details/52012593 )
230+
206231
207232
208233## 8、数字序列中的某一位数字
209234
210235数字以 0123456789101112131415... 的格式序列化到一个字符串中,求这个字符串的第 index 位。
211236
212237``` java
238+ public int getDigitAtIndex(int index) {
239+ if (index< 0 ){
240+ return - 1 ;
241+ }
242+ int place= 1 ;
243+ while (true ){
244+ // place 位的数字的个数
245+ int total = getAmountOfPlace(place);
246+ int bits = total* place; // place 位数字的总位数
247+ if (index< bits){
248+ return getDigitAtIndex(index,place);
249+ }
250+ index -= bits;
251+ place++ ;
252+ }
253+ }
254+
255+ // 获取 place 位的起始数字
256+ // 比如:
257+ // 1 位数的起始数字是 0
258+ // 2 位数的起始数字是 10
259+ // 3 位数的起始数字是 100
260+ private int getBeginNumOfPlace(int place){
261+ if (place== 1 ){
262+ return 0 ;
263+ }
264+ return (int )Math . pow(10 ,(place- 1 ));
265+ }
266+
267+ // 获取 place 位的数字的个数
268+ // 比如:
269+ // 1 位数[0-9]的数字个数是 10
270+ // 2 位数[10-99]的数字个数是 90
271+ // 3 位数[100-999]的数字个数是 900
272+ private int getAmountOfPlace(int place) {
273+ if (place== 1 ){
274+ return 10 ;
275+ }
276+ return (int )Math . pow(10 ,(place- 1 ))* 9 ;
277+ }
213278
279+ // 获取 place 位的所有数字中的第 index 位置的数
280+ private int getDigitAtIndex(int index, int place) {
281+ int beginNumber = getBeginNumOfPlace(place);
282+ int shiftNumber = index/ place; // rangeNumber 表示 index 有多少个 place 位的数
283+ int offset = index% place; // 偏移量
284+ String number = beginNumber+ shiftNumber+ " " ;
285+ return number. charAt(offset)- ' 0' ;
286+ }
214287```
215288
216289
217290
291+ ## 9、圆圈中最后剩下的数
292+
293+ [ 圆圈中最后剩下的数] ( https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking )
294+
295+ ``` java
296+ // 思路:
297+ // 实际上就是约瑟夫环问题:
298+ // 将编号为 0~(N–1)这 N 个人进行圆形排列,按顺时针从 0 开始报数,报到 M–1 的人退出圆形队列,
299+ // 剩下的人继续从 0 开始报数,不断重复。求最后出列者最初在圆形队列中的编号。
300+
301+ // 公式如下:f(N,M) = (f(N-1,M)+M) % N
302+ // N 表示 N 个报数人
303+ // M 表示 报的数
304+ // f(N,M) N个人报数,每报到 (M-1) 时就退出环,最后出列者在圆形队列中的编号。
305+
306+ // 写法一: 循环版本
307+ public int LastRemaining_Solution(int n, int m) {
308+ if (n== 0 ){
309+ return - 1 ;
310+ }
311+ if (n== 1 ){
312+ return 0 ;
313+ }
314+ int f= 0 ;
315+ for (int i= 2 ;i<= n;i++ ){
316+ f= (f+ m)% i;
317+ }
318+ return f;
319+ }
320+ ```
321+
322+ ``` java
323+ // 写法二:递归版本
324+ public int LastRemaining_Solution(int n, int m) {
325+ if (n== 0 ){
326+ return - 1 ;
327+ }
328+ if (n== 1 ){
329+ return 0 ;
330+ }
331+ return (LastRemaining_Solution(n- 1 ,m)+ m)% n;
332+ }
333+ ```
334+
335+ > [ 参考:约瑟夫环问题] ( https://blog.csdn.net/u011500062/article/details/72855826 )
0 commit comments