腾讯2017 秋招+暑期实习 笔试(编码;构造回文;字符移位;有趣的数字)

1 编码

假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 编写一个函数,输入是任意一个编码,输出这个编码对应的Index.

输入描述:

输入一个待编码的字符串,字符串长度小于等于100.

输出描述:

输出这个编码的index

输入例子1:

baca

输出例子1:

16331

思路:

题目还是有依据的:
五笔的编码范围是a到y的25个字母,从1位到4位的编码,
如果将五笔的编码按字典序排序,形成数组如下:a, aa, aaa, aaaa, aaab, aaac, …, b, ba, baa, baaa, baab…yyyx, yyyy

不过还是有些难懂,这个字典序
首先可以分成25个大块,每块是以字母a-y开头(不是x是叉,代表空,不满四个字符)
在这里插入图片描述 第一大块包含多少个呢?如果长度是4,说明都不包含空(x)第一位已经确定,就是a还有三位可选(选25个字母之一),就是252525,长度是3说明有一个空,25*25,长度为2,两个空只剩一个位置可以是25个字母中任意一个,25,长度是1,那就只有a自己了。所以一共是 253+252+25+1

例:bcd
第一位是b所以处在第二大块,result += 1 * (253+252+25+1)
第二位是c, result += 2 (25^2+25+1)+1
第三位是d, result += 3
(25+1)+1 (加一是因为最前面有个空)
第四位是空,不管,因为空就是第一个
result = 17658

例:defc
第一位是d所以处在第四大块,result += 3 * (253+252+25+1)
第二位是e, result += 4 (25^2+25+1)+1
第三位是 f, result += 5
(25+1)+1
第四位是c, result += 2* (1)+1
result = 51567

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

        String str=sc.next();
        int res=0;
        if(str.length()>0){
            res+=(str.charAt(0)-'a')*(25*25*25+25*25+25+1);
        }
        if(str.length()>1){
            res+=(str.charAt(1)-'a')*(25*25+25+1)+1;
        }
        if(str.length()>2){
            res+=(str.charAt(2)-'a')*(25+1)+1;
        }
        if(str.length()>3){
            res+=(str.charAt(3)-'a')*(1)+1;
        }
        System.out.println(res);
    }
}

2 构造回文

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出一个整数,代表最少需要删除的字符个数。

输入例子1:

abcda
google

输出例子1:

2
2

思路

找到str的reverse:str2,求出str和str2的公共最长串的长度,放在int[][] dp中,用动态规划的思路做。

public class HuiWen {
    //构造回文 动态规划
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str=sc.next();
            String str2=new StringBuilder(str).reverse().toString();
            int[][] dp=new int[str.length()+1][str2.length()+1];
            for(int i=1;i<dp.length;i++){
                for(int j=1;j<dp[0].length;j++){
                    dp[i][j]=str.charAt(i-1)==str2.charAt(j-1)?dp[i-1][j-1]+1:Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
            System.out.println(str.length()-dp[str.length()][str2.length()]);
        }
    }
}

3 字符移位

小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出移位后的字符串。

输入例子1:

AkleBiCeilD

输出例子1:

kleieilABCD

public class CharMove {
    //字符移位
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();        ;
        System.out.println(str.replaceAll("[A-Z]","")+str.replaceAll("[a-z]",""));
    }
}

4 有趣的数字

小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,相差最小的有多少对呢?相差最大呢?

输入描述:

输入包含多组测试数据。

对于每组测试数据:

N - 本组测试数据有n个数

a1,a2…an - 需要计算的数据

保证:

1<=N<=100000,0<=ai<=INT_MAX.

输出描述:

对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。

输入例子1:

6
45 12 45 32 5 6

输出例子1:

1 2

public class FindMinMaxCount {
    public static void main(String[] args) {
        //有趣的数字
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int n = sc.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = sc.nextInt();
            }

            Arrays.sort(arr);
            //如果数组中的值全相同,直接两两组合
            if(arr[0]==arr[n-1]){
                int cur=n*(n-1)/2;
                System.out.println(cur+" "+cur);
                continue;
            }

            //treemap中存的是num,和num出现的次数
            TreeMap<Integer,Integer> treeMap=new TreeMap<>();
            for(int i=0;i<n;i++){
                if(treeMap.containsKey(arr[i])){
                    treeMap.put(arr[i],treeMap.get(arr[i])+1);
                }else{
                    treeMap.put(arr[i],1);
                }
            }

            //求差值最小的对数
            int minCount=0;
            //没有重复的数字,求差值最小的组合的对数
            if(treeMap.size()==n){
                int min=Math.abs(arr[1]-arr[0]);
                for(int i=2;i<n;i++){
                    int cur=Math.abs(arr[i]-arr[i-1]);
                    if(cur==min){
                        minCount++;
                    }else if(min>cur){
                        min=cur;
                        minCount=1;
                    }
                }
            }else{//有重复数字的话,求差值最小的组合的对数
                for(int key:treeMap.keySet()){
                    int val=treeMap.get(key);
                    if(val>1){
                        minCount+=val*(val-1)/2;
                    }
                }
            }

            //求差值最大的对数
            List<Integer> list=new ArrayList<>(treeMap.keySet());
            int maxCount=treeMap.get(list.get(0))*treeMap.get(list.get(list.size()-1));
            System.out.println(minCount+" "+maxCount);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值