腾讯2017暑期实习生编程题

上次做了乐视的暑期实习生编程题:http://blog.csdn.net/chenchaofuck1/article/details/51700143
今天也做了腾讯的的实习生编程题,整体感觉要比乐视的题难一些,但也没有涉及非常难的算法,题如下:

1.构造回文
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
腾讯2017暑期实习生编程题_第1张图片

代码
这题刚开始看有点难度,和在剑指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吗?
腾讯2017暑期实习生编程题_第2张图片

代码
这道题不能采用额外的空间,所以必须两两进行交换,所以采用类似于冒泡的算法,把小写字符冒到大写字母之前就可以了。

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;iif(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个数,两两组成二元组,差最小的有多少对呢?差最大呢?
腾讯2017暑期实习生编程题_第3张图片
腾讯2017暑期实习生编程题_第4张图片
代码
这道题刚开始我用的是先排序,再统计,时间复杂度是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[n];
            Map map=new HashMap();
            for(int i=0;iin.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 map){
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;
        for(int i=0;iif(nums[i]>max)
                max=nums[i];

            if(nums[i]int maxNumberCount=map.get(max);
        int minNumberCount=map.get(min);

        int maxResult=maxNumberCount*minNumberCount;
        return maxResult;
    }
    public static int getMinResult(Map map){
        int minResult=0;
        boolean containSameNumber=false;
        Set keySet=map.keySet();
        Iterator 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 list=new ArrayList();
            list.addAll(keySet);
            Collections.sort(list);
            int distance=Integer.MAX_VALUE;
            for(int i=0;i1;i++)
            {
                int x=list.get(i+1) - list.get(i);
                if( x1;
                }
                else if(x == distance)
                {
                    minResult++;
                }

            }
        }
        return minResult;
    }
}

代码虽然通过了用例,但可能还是有错误地方,仅供参考

你可能感兴趣的:(数据结构与算法)