一道腾讯面试题的思考:到底谁会赢?

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

       有甲乙两家伙用一个英语单词玩游戏(无聊的人还是很多的!!!)。两个人轮流进行,每个人每次从中删掉任意一个字母,如果剩余的字母序列是严格单调递增的(按字典序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<StringBuilder> ascendingList = new java.util.ArrayList<StringBuilder>();
		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<StringBuilder>()
		{

			@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的算法,欢迎跟帖,语言不限!

2013 CSDN博客之星评选

时间: 2024-10-23 15:13:09

一道腾讯面试题的思考:到底谁会赢?的相关文章

一道腾讯面试题

view plainprint? /**    * 已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10.    */    using System;    using System. Collections.Generic;    using System.Linq;    using System.Text;        namespace  Console Application1    {        class Progr

阿里巴巴一道智力题笔试题

问题描述 阿里巴巴一道智力题笔试题 有三张牌A,B,C,其中一张是King.如果你押中了King,那么就获胜,否则就输.现在你选择了押其中的一张牌1,电脑帮你排除了另外两张牌中的一张2,那么你是否重新选择押3,从而更容易获胜? http://www.manong1024.com/q/403 解决方案 google 三扇门问题真怀疑这是不是阿里的题,感觉很低级很low,像庙会灯谜上的题. 解决方案二: 假设挑选A其为king的概率p=1/3剩下的BC中为king的概率p=2/3.假设主持人又给你排

一道蛋疼的面试题

题目: 1 int n = 20; 2 for(int i = 0; i < n; i--){ 3     printf("*"); 4 } 只能增加或是修改其中的一个字符,让程序输出20个"*". 答案: 1 //第一种解法:在for循环中给 i 加一个负号 2 for(int i = 0; -i < n; i--) 3    4 //第二种解法:在for循环中把 i-- 变成 n-- 5 for(int i = 0; i < n; n--) 6

c str-c++中c_str()函数--一道简单的机试题

问题描述 c++中c_str()函数--一道简单的机试题 题目描述:输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串.输入:测试数据有多组,输入字符串.输出:对于每组输入输出处理后的结果.样例输入:bacd样例输出:abcd源代码: #include#include#include#include#includeusing namespace std; int main() { int i = 0jnum; string in; char* arr = new char

jquery js-今天做了一道神奇的笔试题

问题描述 今天做了一道神奇的笔试题 如何用一行jquer实现动画轮播 <div class="slide"> <img src="1.png"> <img src="2.png"> <img src="3.png"> <img src="4.png"> </div> 解决方案 也就是你运气好,让别的看见又得告诉你思路了 var spee

摩托罗拉RAZR与iPhone 4S语音功能 到底谁能赢

今年语音技术在智能手机上得到了很大的发展.苹果iPhone 4S内置的Siri功能也是引发了语音狂潮,而对于很多的用户来说Android手机上要有类似的功能就好了.这不机会来了,国外今日一则视频展示了摩托罗拉RAZR与iPhone 4S语音功能的对比,到底谁能赢呢? <IMG width="500" style="BORDER-BOTTOM: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-TOP: black

一道阿里巴巴海量数据笔试题

问题描述 在看到的一道笔试题:搜索引擎的日志要记录所有查询串,有一千万条查询,不重复的不超过三百万.要统计最热门的10条查询串.内存<1G.字符串长0-255(1)主要解决思路(2)算法及其复杂度分析 解决方案 解决方案二:我能想到的就是哈希+堆排序了

由一道淘宝面试题到False sharing问题

今天在看淘宝之前的一道面试题目,内容是 在高性能服务器的代码中经常会看到类似这样的代码: typedef union { erts_smp_rwmtx_t rwmtx; byte cache_line_align_[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_smp_rwmtx_t))]; }erts_meta_main_tab_lock_t; erts_meta_main_tab_lock_t main_tab_lock[16]; 请问其中用来填充的c

一道经典JAVA面试题

问题描述 客户端从服务器读取数据,是要花费一定时间的.客户端发送价格1.1给服务器猴返回客户端的数据如下格式:价格排名1.11001.2100..........2.0100客户端发送价格2.1给服务器猴返回客户端的数据如下格式:2.1992.2992.398..........3.096价格是递增的,排名也是递增的,也可能与以前相同.价格的范围是1-100如何以最快的方法找到客户端要的排名对应的最低价格.如:需要找第2名,最低价格 解决方案 解决方案二:二分查找解决方案三:二分算法想过,不过这