博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一道腾讯面试题的思考:到底谁会赢?
阅读量:5909 次
发布时间:2019-06-19

本文共 3214 字,大约阅读时间需要 10 分钟。

最近看到一道腾讯面试题,觉得很有意思。题干如下:

       有甲乙两家伙用一个英语单词玩游戏(无聊的人还是很多的!!!)。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序a < b < c <....<z,假设单词字母不区分大小写,也就是说,a与A算相等),则这个人胜利。假设两个人都足够聪明(即如果有赢的方案,都不会选输的方案 ),甲先开始,问他能赢么?

输入: 一连串英文小写字母,长度任意(当然要在计算机能承受的范围内),保证最开始的状态不是一个严格单增的序列。

输出:1表示甲可以赢,0表示甲不能赢。

例如: 输入 bad, 则甲可以删掉b或者a,剩余的是ad或者bd,他就赢了,输出1。

又如: 输入 aaa, 则甲只能删掉1个a,乙删掉一个a,剩余1个a,乙获胜,输出0。

下面给出我用Java实现的算法,如果大家有其他的实现方法,欢迎跟帖和探讨。语言不限

       我的基本实现思路将给定的单词分成若干个单调递增的序列。然后按每个序列中包含单词个数多少进行递减排序,也就是说,排在前面的单调递增序列中包含的字母个数最少。然后由甲开始从排在前面的递增序列中选择一个字母。直到该递增序列中的字母全部被选中。然后继续从下一个递增序列选择字母。按着这样的方法做,直到剩下最后一个单调递增序列,随最后选择了倒数第二个单调递增序列中的最后一个字母,谁就赢了。

例如,单词hela,可以分为三个单调递增序列:h、a、el。从甲开始选择。

甲:h

乙:a

由于a是倒数第二个单调递增序列的最后一个字母,所以乙赢了。

对于单词money可以分成三个单调递增序列:mo、n、ey。排序后:n、mo、ey。

甲:n

乙:m

甲:o

所以甲赢。

具体的实现算法如下:

public class Test{    //  实现算法的方法,in为一个给定的单词    public static int who(String in)    {        //  基本思路就是找到该单词中所有递增的子序列,然后从字符最少的子序列甲乙轮回删除字母,直到还剩下最后一个子序列为止        //  谁删除了最后一个字母,谁就赢了!                //  in不能为null        if(in == null)            return 0;        //  单词至少需要有一个字母        if(in.length() == 0)            return 0;        in = in.toLowerCase();   //  都变成小写字母        //  所有递增数列集合        java.util.List
ascendingList = new java.util.ArrayList
(); char lastChar = in.charAt(0); StringBuilder sb = new StringBuilder(); // 存储当前递增的字符列表 sb.append(lastChar); for(int i = 1; i < in.length(); i++) { // 当前字符属于当前的递增序列 if(in.charAt(i) > lastChar) { sb.append(in.charAt(i)); } // 当前字符属于下一个递增序列,所以需要存储上一个递增序列 else { ascendingList.add(sb); sb = new StringBuilder(); sb.append(in.charAt(i)); } lastChar = in.charAt(i); } if(sb.length() > 0) { ascendingList.add(sb); } // 下面就开始游戏了 // 从甲开始删字母,从字符最少的递增序列开始删除第一个字母,直到之后只剩下一个递增序列为止,谁删除的最后一个之母,谁就赢了 // 这里本应该判断如果单词本身就是递增序列,那么甲就win了,不过既然题目说没有这种情况,所以就注释掉了 /*if(ascendingList.size() == 1) { return 1; }*/ java.util.Collections.sort(ascendingList, new java.util.Comparator
() { @Override public int compare(StringBuilder sb1, StringBuilder sb2) { if(sb1.length() > sb2.length()) { return 1; } else if(sb1.length() == sb2.length()) { return 0; } else { return -1; } } }); int win = 0; // 1代表甲赢,0代表乙赢 while(ascendingList.size() > 1) { if(win == 0) win = 1; // 甲开始 else win = 0; // 乙开始 // 删除第一个递增序列的第一个字母,如果该递增序列 ascendingList.get(0).delete(0, 1); if(ascendingList.get(0).length() == 0) { ascendingList.remove(0); } } return win; } public static void main(String[] args) { System.out.println(who("money")); }}

谁有更NB的算法,欢迎跟帖,语言不限!

 
 
 

转载地址:http://noppx.baihongyu.com/

你可能感兴趣的文章
oschina程序开发
查看>>
“正在注册字体”问题解决
查看>>
iOS开发-OpenGL ES入门教程1
查看>>
Java 设计模式专栏
查看>>
使用ASP.NET Atlas SortBehavior实现客户端排序
查看>>
图像滤镜处理算法:灰度、黑白、底片、浮雕
查看>>
Office文档出错的几种原因与解决方法
查看>>
正则表达式 学习笔记1.1
查看>>
《从零开始学Swift》学习笔记(Day 40)——析构函数
查看>>
更改UIView的背景
查看>>
APUE第15章学习扎记之程序的存储区布局试验
查看>>
三目运算判断jsp脚本里面的值
查看>>
sshtunnel在本地访问云服务器mysql
查看>>
CDN相关
查看>>
查找(AVL平衡二叉树)
查看>>
Linux常用基本命令( rmdir, rm, mv )
查看>>
POJ2406 Power Strings(KMP)
查看>>
JavaScript-console的使用_016
查看>>
两种方式设置iframe的高度区别
查看>>
Iterator 和 for...of 循环
查看>>