腾讯2017暑期实习生编程题
2016-06-19 16:55
253 查看
上次做了乐视的暑期实习生编程题:/article/11856495.html
今天也做了腾讯的的实习生编程题,整体感觉要比乐视的题难一些,但也没有涉及非常难的算法,题如下:
1.构造回文
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
代码
这题刚开始看有点难度,和在剑指offer上做的求最长回文串不同,这道题可以删除不连续的字符,所以可以将字符串反转,求两个字符串的最长公共子序列,像这种字符串比较一般都可以使用动态规划求解。
有关字符串比较的可以看文本比较算法Needleman/Wunsch算法,动态规划算法之:最长公共子序列 & 最长公共子串(LCS)。
2.算法基础-字符移位
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
代码
这道题不能采用额外的空间,所以必须两两进行交换,所以采用类似于冒泡的算法,把小写字符冒到大写字母之前就可以了。
3. 有趣的数字
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
代码
这道题刚开始我用的是先排序,再统计,时间复杂度是nlogn。过后我发现有些人用的是map来统计,最优情况下时间复杂度更好一些,算差最大的对数就是最小的个数乘以最大数的个数,算差最小的对数要区分是否有重复的数,如果没有需要先排序,再相邻两个数最小的差。
代码虽然通过了用例,但可能还是有错误地方,仅供参考
今天也做了腾讯的的实习生编程题,整体感觉要比乐视的题难一些,但也没有涉及非常难的算法,题如下:
1.构造回文
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
代码
这题刚开始看有点难度,和在剑指offer上做的求最长回文串不同,这道题可以删除不连续的字符,所以可以将字符串反转,求两个字符串的最长公共子序列,像这种字符串比较一般都可以使用动态规划求解。
有关字符串比较的可以看文本比较算法Needleman/Wunsch算法,动态规划算法之:最长公共子序列 & 最长公共子串(LCS)。
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner in=new Scanner(System.in); while(in.hasNext()){ String str1=in.nextLine(); String str2=new StringBuilder(str1).reverse().toString(); System.out.println(str1.length()-LCS(str1,str2)); } in.close(); } public static int LCS(String str1,String str2){ // 设置字符串长度 int len1= str1.length(); int len2=str2.length(); // 具体大小可自行设置 // 构造二维数组记录子问题x[i]和y[i]的LCS的长度 int[][] record = new int[len1 + 1][len2 + 1]; // 从后向前,动态规划计算所有子问题。 for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (str1.charAt(i-1) == str2.charAt(j-1)) record[i][j] = record[i-1][j-1] + 1;// 状态转移方程 else{ record[i][j] = Math.max(record[i-1][j], record[i][j-1]);// 状态转移方程 //record[i][j] = Math.max(tmp,record[i-1][j-1]); } } } return record[len1][len2]; } }
2.算法基础-字符移位
小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?
代码
这道题不能采用额外的空间,所以必须两两进行交换,所以采用类似于冒泡的算法,把小写字符冒到大写字母之前就可以了。
import java.util.Scanner; public class Main{ public static void main(String[] arg){ Scanner in=new Scanner(System.in); while(in.hasNextLine()){ String s=in.nextLine(); StringBuilder sb=new StringBuilder(s); System.out.println(change(sb)); } in.close(); } public static String change(StringBuilder sb){ int len=sb.length(); for(int i=1;i<len;i++){ if(isLowerCase(sb.charAt(i))){ int x=i; while(x>=1 && !isLowerCase(sb.charAt(x-1))){ char tmp=sb.charAt(x-1); sb.setCharAt(x-1, sb.charAt(x)); sb.setCharAt(x, tmp); x=x-1; } } } return sb.toString(); } public static boolean isLowerCase(char c){ if(c>='a' && c<='z') return true; return false; } }
3. 有趣的数字
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?
代码
这道题刚开始我用的是先排序,再统计,时间复杂度是nlogn。过后我发现有些人用的是map来统计,最优情况下时间复杂度更好一些,算差最大的对数就是最小的个数乘以最大数的个数,算差最小的对数要区分是否有重复的数,如果没有需要先排序,再相邻两个数最小的差。
import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.Set; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub Scanner in=new Scanner(System.in); while(in.hasNext()) { int n=in.nextInt(); int[] nums=new int ; Map<Integer,Integer> map=new HashMap<Integer,Integer>(); for(int i=0;i<n;i++){ nums[i]=in.nextInt(); if(map.containsKey(nums[i])) { int t=map.get(nums[i]); map.put(nums[i], ++t); } else { map.put(nums[i], 1); } } int minResult=getMinResult(map); int maxResult=getMaxResult(nums, map); System.out.println(minResult+" "+maxResult); } in.close(); } public static int getMaxResult(int[] nums,Map<Integer,Integer> map){ int max=Integer.MIN_VALUE; int min=Integer.MAX_VALUE; for(int i=0;i<nums.length;i++) { if(nums[i]>max) max=nums[i]; if(nums[i]<min) min=nums[i]; } int maxNumberCount=map.get(max); int minNumberCount=map.get(min); int maxResult=maxNumberCount*minNumberCount; return maxResult; } public static int getMinResult(Map<Integer,Integer> map){ int minResult=0; boolean containSameNumber=false; Set<Integer> keySet=map.keySet(); Iterator<Integer> it=keySet.iterator(); //查看是否有重复数字 while(it.hasNext()) { int t=it.next(); int times=map.get(t); if(times>1) { containSameNumber=true; minResult+=times*(times-1)/2; } } //如果没有重复,进行排序.找相邻最小的对数 if(!containSameNumber) { ArrayList<Integer> list=new ArrayList<Integer>(); list.addAll(keySet); Collections.sort(list); int distance=Integer.MAX_VALUE; for(int i=0;i<list.size()-1;i++) { int x=list.get(i+1) - list.get(i); if( x<distance) { distance = x; minResult=1; } else if(x == distance) { minResult++; } } } return minResult; } }
代码虽然通过了用例,但可能还是有错误地方,仅供参考
相关文章推荐
- 深入理解JAVA集合系列二:ConcurrentHashMap源码解读
- python中splite()返回值
- Python-zip函数
- Spring的depends-on属性Bean依赖
- JAVA如何控制结果集ResultSet的指针,使之能够上下移动
- 不同工具下的矩阵乘法速度测试
- Java运算符优先级
- python3 实现的人人影视网站自动签到
- Spring-----自定义属性编辑器
- Java中的Infinity和NaN
- 史上最全的ASP.NET MVC路由配置,以后RouteConfig再弄不懂神仙都难救你啦~
- Zookeeper Api(java)入门与应用
- JDK与设计模式:职责链模式
- C++内存分配
- eclipse的编辑代码自动提示功能
- struts2-拦截器(二)方法拦截器
- Python的字节编译
- eclipse调节java字体大小和xml中字体大小的方法
- HBase Java API
- Thinking in Java 第3章 控制程序流程 总结