腾讯2017暑期实习生编程题一——回文

腾讯2017暑期实习生编程题一——回文

题目来自牛客网,感谢!

给定字符串,从中移除若干项使其成为回文,求最小移除项数
回文:倒置后与自身等同的字符串

输入格式

若干行,每行输入一个字符串

输出格式

若干行,每行输出对应的最小移除项数

输入范例

abcda
google

输出范例

2
2

感觉这道题非常之难,白想了半天之后,决定用结晶算法(我自己发明的词哈哈),令某一个数或某一对连续的相同数为,令两个指针分别向两侧扫描,扫描结果存入Map供对方比对,匹配到数对后,将数对与结合,成为新的进行下一次扫描。
非常可惜这个算法是有缺漏的。其问题出在每次扫描都要进行到字符串结尾,递归的情况下复杂度接近 O ( n n ) O(n^n) O(nn),是只存在于教科书里的错误算法呢(笑)
代码实现使用了较为简洁的一个版本,未能正常处理形如下例的输入

abccaba

我的代码实现

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Palindrome {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		String s = null;
		List<char[]> cList = new ArrayList<char[]>();
		while (sc.hasNextLine() && !((s = sc.nextLine()).equals("")))
			cList.add(s.toCharArray());
		sc.close();
		for (char[] c : cList) {
			int x = c.length - 1;
			for (int i = 0; i < c.length; i++) {
				x = Math.min(x, grow(c, i, i));
				if (i > 0 && c[i] == c[i - 1])
					x = Math.min(x, grow(c, i - 1, i));
			}
			System.out.println(x);
		}
	}

	public static int grow(char[] c, int top, int bot) {
		if (top == 0 && bot == c.length - 1)
			return 0;
		int p = top;
		int q = bot;
		Map<Character, Integer> mapp = new HashMap<Character, Integer>();
		Map<Character, Integer> mapq = new HashMap<Character, Integer>();
		while (p != 0 || q != c.length - 1) {
			if (p > 0) {
				p--;
				if (mapq.containsKey(c[p]))
					return (mapq.get(c[p]) - p) - (bot - top) - 2 + grow(c, p, mapq.get(c[p]));
				else
					mapp.put(c[p], p);
			}
			if (q < c.length - 1) {
				q++;
				if (mapp.containsKey(c[q]))
					return (q - mapp.get(c[q])) - (bot - top) - 2 + grow(c, mapp.get(c[q]), q);
				else
					mapq.put(c[q], q);
			}
		}
		return (q - p) - (bot - top) + grow(c, p, q);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值