今天开始讲和大家坚持打卡面试非常重要算法练习---剑指offer,希望我们能一起肝。

1 题目描述

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…m-1报数….这样下去….直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

如果没有小朋友,请返回-1

2 思路----Py

约瑟夫问题。使用list模拟循环链表,其中使用cur指向list的下标。当cru移动到list末尾直接指向list的头部,当删除一个数后list的长度和cur的值相等则cur指向``0

3 思路-----java

  • 创建n个元素的list

  • 从0个元素开始,计数,每到m-1就将对应元素删除

  • 重复计数删除元素直到结束

3 代码实现

c++版本

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    
{
        if(n<1||m<1)return -1;
        vector<int>a;
        for(int i=0;i<n;i++){
            a.push_back(i);
        }
        int now=0;
        while(a.size())
        {
            now=(now+m-1)%a.size();
            a.erase(a.begin()+now);
            if(a.size()==1)break;
        }
        return a[0];
    }
};

java版本

import java.util.ArrayList;
import java.util.List;
public class Solution {
   public static int LastRemaining_Solution(int n, int m) {
        if (n < 1 || m < 1)
            return -1;
        // 初始化一个数据容器
        List<Integer> list = new ArrayList<Integer>();
        // 向容器添加数据
        for (int i = 0; i < n; i++) {
            list.add(i);
        }
        //设置跟踪标志,index这个值很重要
        int index = 0;
        while (list.size() > 1) {
            //每一次循环都是在寻找第m个元素
            for (int j = 1; j < m; j++) {
                if (index == list.size() - 1)
                    index = 0;
                else
                    index++;
            }
            //移除目标元素
            list.remove(index);
            if (index == list.size())
                index = 0;
        }
        return list.get(0);
    }
}

python版本

class Solution:
    def LastRemaining_Solution(self, n, m):
        # write code here
        if n < 1 or m < 1:
            return
        childNum = list(range(n))
        print(childNum)
        cur = 0  # 指向list的指针
        while len(childNum) > 1:
            for i in range(1,m):
                cur += 1
                # 当指针移到list的末尾,则将指针移到list的头
                if cur == len(childNum):
                    cur = 0
            # 删除一个数,此时由于删除之后list的下标随之变化
            # cur指向的便是原数组中的下一个数字,此时cur不需要移动
            childNum.remove(childNum[cur])
            if cur == len(childNum):  # list的长度和cur的值相等则cur指向0
                cur = 0
        return childNum

4 唠嗑

2020年7月31日打卡,打卡格式"打卡XX天"。暖蓝汇聚大家一起,探讨简历修改,面试经历分享,尽全力让大家能在2020找到理想的工作。如果你想加入,加我拉你进面试交流群。