剑指offer刷题记录——抽象建模能力

扑克牌顺子

题目描述

LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张_)…他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子…LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。

实现思路

首先将数组排序,然后记录0的个数(大小王的个数),判断是否存在除0以外重复的数字,存在的话就返回错误。再求除0以为各个数之间的间隔并累加起来,若最后这个数大于大小王的数则不可能形成顺子,若小于等于的话则可以形成顺子。

具体实现

class Solution {
public:
    bool IsContinuous( vector<int> numbers ) {
        int len = numbers.size();
        if(len<=0)
            return false;
        int jokers=0;
        int dis=0;
        sort(numbers.begin(),numbers.end());
        for(int i=0;i<len-1;i++){
            if(numbers[i]==0){
                jokers++;
                continue;
            }
            if(numbers[i]==numbers[i+1])
                return false;
            dis+=numbers[i+1]-numbers[i]-1;
        }
        if(dis>jokers)
            return false;
        return true;
        
    }
};

 

孩子们的游戏(圆圈中最后剩下的数)

题目描述

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

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

实现思路

这道题目很多人用数学归纳法推导出了一个公式进行求解,但是我认为题目的本意还是要让我们来合理建模模拟这个过程。
最适合的模拟方法就是用链表来模拟了,依次将小朋友的序号放入链表中,然后在只剩一个小朋友之前,不断地将第m个同学erase。用一个指针指向erase后所在的位置,要注意的是只要有指针移动,就一定要判断是否移动到了容器后面的位置,如果是的话就赋值为容器的第一个位置,以此来模拟环的过程。最后指针会指向最后一个孩子。

具体实现

class Solution {
public:
    int LastRemaining_Solution(int n, int m)
    {
        if(n<1||m<1) return -1;
        list<int> circle;
        for(int i=0;i<n;i++){
            circle.push_back(i);
        }
        list<int> ::iterator cur = circle.begin();
        while(circle.size()>1){
            for(int i=1;i<m;i++){
                cur++;
                if(cur==circle.end())
                    cur=circle.begin();
            }
            list<int> ::iterator next = ++cur;
            cur--;
            if(next==circle.end())
                next=circle.begin();
            circle.erase(cur);
            cur=next; 
        }
        return *cur;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值