算法刷题——快手篇

快手(入门)

KS9字符串排序

描述

月神拿到一个新的数据集,其中每个样本都是一个字符串,样本的的后六位是纯数字,月神需要将所有样本的后六位数字提出来,转换成数字,并排序输出。

注意: 这里的排序并不是针对每个字符串的后六位,而是需要按数字大小顺序输出所有样本的后六位数字。

月神要实现这样一个很简单的功能确没有时间,作为好朋友的你,一定能解决月神的烦恼,对吧。

数据范围: 字符串长度满足 1 ≤ n ≤ 100 ,每组测试中包含 1 ≤ m ≤100 个字符串

输入描述:

每个测试用例的第一行是一个正整数 M ,表示数据集的样本数目

接下来输入 M 行,每行是数据集的一个样本,每个样本均是字符串,且后六位是数字字符。

输出描述:

对每个数据集,输出所有样本的后六位构成的数字排序后的结果(每行输出一个样本的结果)

示例:

输入:

4
abc123455
cba312456
boyxx213456
cdwxa654321

输出:

123455
213456
312456
654321

解题

import java.util.*;

public class Main {
    public static void main(String[] args) {

        // 根据输入的组数获取创建数组容量
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] arr = new int[n];
        
        // 循环输入字符串
        for (int i = 0; i < n ; i++) {
            String str = sc.next();
            
            // 截取输入字符串中需要的部分,并转为int类型
            int num = Integer.parseInt(str.substring(str.length() - 6, str.length()));
            
            // 将num有序放入到数组中(按从小到大排序)
            int j = i;
            for (; j > 0 && arr[j - 1] > num; j--) {
                arr[j] = arr[j - 1];
            }
            arr[j] = num;
            
        }
        
        // 输出数组
        for (int i: arr) {
            System.out.println(i);
        }
        
    }
}

KS12游戏海报

描述

小明有 26 种游戏海报,用小写字母 “a” 到 “z” 表示。小明会把游戏海报装订成册(可能有重复的海报),册子可以用一个字符串来表示,每个字符就表示对应的海报,例如 abcdea 。小明现在想做一些“特别版”,然后卖掉。特别版就是会从所有海报(26种)中随机选一张,加入到册子的任意一个位置。那现在小明手里已经有一种海报册子,再插入一张新的海报后,他一共可以组成多少不同的海报册子呢?

数据范围:输入的字符串长度满足 1 ≤ n ≤ 20

输入描述:

海报册子的字符串表示

输出描述:

一个整数,表示可以组成的不同的海报册子种类数

解题

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.next();
        
        // 获取字符串长度
        int len = str.length();
        
        // 有26个字母,有 len+1 个空,有len个可能重复的字符
        System.out.println((len + 1) * 26 - len);
    }
}

KS17字符串归一化

描述

通过键盘输入一串小写字母 (a~z) 组成的字符串。请编写一个字符串归一化程序,统计字符串中相同字符出现的次数,并按字典序输出字符及其出现次数。例如字符串"babcc"归一化后为"a1b2c2"

数据范围:输入的字符串长度满足 1 ≤ n ≤ 106 ,保证输入中仅包含小写的英文字母

输入描述:

每个测试用例每行为一个字符串,以’\n’结尾,例如cccddecca

输出描述:

输出压缩后的字符串ac5d2e

解题(法一)

import java.util.*;

/**
	用26个字母的(ASCII法)
*/
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        
        // 创建存储26个字母的数组
        int[] arr = new int[26];
        
        // 遍历得到的字符串
        char c ;
        for (int i = 0;i < str.length(); i++) {
            c = str.charAt(i);  // 通过遍历获取每一个字符
            arr[(int)c - 97] ++;  // a的ASCII为97
        }
        
        // 遍历输出存储 > 0
        for (int i = 0;i < arr.length; i++) {
            if (arr[i] > 0) {  // 大于0就表示字符串中有
                System.out.print((char)(i + 97));  // 逆推回字母
                System.out.print(arr[i]);
            }
        }
    }
}

解题(法二)

import java.util.*;

/**
	hashmap存储法
*/
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        
        char[] chars = str.toCharArray();  // 将字符串转为字符数组
        
        // 定义存储【字符】和【字符数量】的hashmap
        HashMap<Character, Integer> map = new HashMap<>();  
        
        for (int i = 0;i < str.length(); i++) {  // 遍历字符数组
            
            // 如果map中有这个键【chars[i]】,就给这个键的值 +1,没有就注入一个键并且 值=1
            if (map.containsKey(chars[i])) {
                map.put(chars[i], map.get(chars[i]) + 1);
            }else {
                map.put(chars[i], 1);
            }
        }
        
        // 将hashmap转为字符串
        int temp = 97; // 或者'a','a'=97
        StringBuilder sbd = new StringBuilder();
        for (int i = 0; i < 26; i++) {
            char ch = (char) temp;  // 强转为字符(26个字母)
            if (map.containsKey(ch)) {  // hashmap中有的键
                sbd.append(ch).append(map.get(ch));  // 将键和值一起存进去
            }
            temp++;  // 下一个字母
        }
        
        // 输出字符串
        System.out.println(sbd);
    }
}

快手(简单)

KS6字符串长度最大乘积

描述

已知一个字符串数组words,要求寻找其中两个没有重复字符的字符串,使得这两个字符串的长度乘积最大,输出这个最大的乘积。如:

words=[“abcd”,“wxyh”,“defgh”], 其中不包含重复字符的两个字符串是"abcd"和"wxyh",则输出16

words=[“a”,“aa”,“aaa”,“aaaa”], 找不到满足要求的两个字符串,则输出0

数据范围:输入的字符串长度满足2 ≤ n ≤ 100 ,保证只包含小写字母

输入描述:

[“a”,“ab”,“abc”,“cd”,“bcd”,“abcd”]

输出描述:

4

解题(法一)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        
        // 提取完整的字符串
        str = str.substring(1, str.length() - 1);  // 去掉输入的'[' 和 ']'字符
        String[] strs = str.split(",");  // 先根据 ',' 来简单筛选字符数组中的字符串
        for (int i = 0; i < strs.length; i++) {
            if (strs[i].length() == 0) {
                continue;
            }
            // 去掉简单筛选的头尾,即 " 和 ",得到完整的字符串
            strs[i] = strs[i].substring(1, strs[i].length() - 1);
        }
        
        int max = 0;  // 记录不重复字符串的长度乘积
        HashSet<Character> set = new HashSet<>();  // 存储一个字符串的每个字符
        
        // 控制字符串和后面的比较,在依次递进
        for (int i = 0;i < strs.length; i++) {
            // 控制第 j 个字符串和后面的比较
            for (int j = i + 1; j < strs.length; j++) {
                int index = 0;  // 主要用户记录该字符串索引到的位置
                
                // 将字符串的字符一个个存入set中当作key
                for (; index < strs[i].length(); index++) {
                    set.add(strs[i].charAt(index));
                }
                
                // 如果有重复的就退出,进而index != strs[j].length()
                for (index = 0;index < strs[j].length(); index++) {
                    if (set.contains(strs[j].charAt(index))) {
                        break;
                    }
                }
                
                // 判断前面的for是否有退出
                if (index == strs[j].length()) {
                    int temp = strs[i].length() * strs[j].length();
                    if (temp > max) {
                        max = temp;
                    }
                }
                
                set.clone();  // 清除set内容,为下一个字符串准备
            }
        }
        System.out.println(max);
    }
}

解题(法二)

相对法一:没有使用HashSet而是直接使用字符串进行对比

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        
        // 提取完整的字符串
        str = str.substring(1, str.length() - 1);  // 去掉输入的'[' 和 ']'字符
        String[] strs = str.split(",");  // 先根据 ',' 来简单筛选字符数组中的字符串
        for (int i = 0; i < strs.length; i++) {
            if (strs[i].length() == 0) {
                continue;
            }
            // 去掉简单筛选的头尾,即 " 和 ",得到完整的字符串
            strs[i] = strs[i].substring(1, strs[i].length() - 1);
        }
        
        int max = 0;  // 记录不重复字符串的长度乘积
        
        // 控制字符串和后面的比较,在依次递进
        for (int i = 0;i < strs.length; i++) {
            // 控制第 j 个字符串和后面的比较
            for (int j = i + 1; j < strs.length; j++) {
                int index = 0;  // 主要用户记录该字符串索引到的位置
                
               // 如果有重复的就退出,进而index != strs[j].length()
               for (;index < strs[j].length(); index++) {
                   if (strs[i].contains(strs[j].substring(index, index + 1))) {
                       break;
                   }
               }
                
                // 判断前面的for是否有退出
                if (index == strs[j].length()) {
                    int temp = strs[i].length() * strs[j].length();
                    if (temp > max) {
                        max = temp;
                    }
                }
            }
        }
        System.out.println(max);
    }
}

KS7今年的第几天

描述

输入年、月、日,计算该天是本年的第几天。

输入:

包括三个整数年、月、日。

输出:

输出一个整数,代表Input中的年、月、日对应本年的第几天。

数据范围:输入的年 1 ≤ y ≤ 3000 ,输入的月满足 1 ≤ m ≤ 12 , 输入的日满足1 ≤ d ≤ 31

输入描述:

输入:1990 9 20

输出描述:

输入:263

解题

import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 获取年月日信息
        Scanner sc = new Scanner(System.in);
        int year = sc.nextInt();
        int mon = sc.nextInt();
        int day = sc.nextInt();
        
        // 定义一年中每个月的天数(2月再做判断),索引即月数
        int[] mons = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        
        // 判断2月份天数
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            mons[1] = 29;
        }
        
        // 存储天数(先存储当月天数再存储当月前的每月的天数)
        int days = day;  
        for (int i = 0;i < mon - 1; i++) {
            days += mons[i]; 
        }
        
        System.out.println(days);
    }
}

KS8数字序列第n位的值

描述

有一个无限长的数字序列1,2,2,3,3,3,4,4,4,4,5,5,5,5,5。。。(数字序列从1开始递增,且数字k在该序列中正好出现k次),求第n项是多少

数据范围:1 ≤ n ≤ 109

输入描述:

输入为一个整数n

输出描述:

输出一个整数,即第n项的值

解题

import java.util.Scanner;
/*
    根据索引(1+2+3+4)判断,小于或等于索引的即为要输出的数字
*/
public class Main {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int index = input.nextInt();
        
        int n = 1;  // 记录到的索引最大范围
        for (int num = 1;num <= index; n++) {
            num += n;
        }
        System.out.println(n - 1);
    }
}

KS21解析加减法运算

描述

解析加减法运算

如:

输入字符串:“1+2+3” 输出:“6”

输入字符串:“1+2-3” 输出:“0”

输入字符串:“-1+2+3” 输出:“4”

输入字符串:“1” 输出:“1”

输入字符串:“-1” 输出:“-1”

已知条件:输入的运算都是整数运算,且只有加减运算

要求:输出为String类型,不能使用内建的eval()函数

数据范围:计算过程中所有值满足 ∣val∣ ≤ 106 ,输入的字符串长度满足 1 ≤ *n *≤ 106

输入描述:

输入字符串:“1+2+3”

输出描述:

输出:“6”

解题

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        
        int num = 0;  // 记录运算值
        int start = 0;  // 记录一个数值的开始索引
        int end = 1;   // 记录一个数值的结束索引
        
        for(; end<str.length(); end++){
            // 确保是完整的数据,当遇到下一个运算符号的时候才进入运算
            if(str.charAt(end) == '+' || str.charAt(end) == '-'){
                num += Integer.parseInt(str.substring(start, end));
                start = end;
            }
        }
        // 最后一个没有下一个运算符号了,所以单独处理
        num += Integer.parseInt(str.substring(start, end));
        System.out.println(num);
    }
}

KS20字符串压缩

描述

对字符串进行 RLE 压缩,将相邻的相同字符,用计数值和字符值来代替。例如:aaabccccccddeee,则可用 3a1b6c2d3e 来代替。

数据范围:字符串长度满足 1 \le n \le 10^5 \1≤n≤105

输入描述:

输入为a-z,A-Z的字符串,且字符串不为空,如aaabccccccddeee

输出描述:

压缩后的字符串,如3a1b6c2d3e

解题

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        char[] chs = str.toCharArray();  // 将字符串转为字符数组
        
        int count = 0;  // 记录连续的字符长度
        for (int i = 0;i < chs.length; i++) {
            count += 1;
            // 如果是下一个不连续或者是最后一个就
            if (i == chs.length - 1 || chs[i] != chs[i + 1]) {
                System.out.print(count + "" + chs[i]);
                count = 0;
            }
        }
    }
}

KS27二进制中有多少个1

描述

把一个 32-bit 整型转成二进制,其中包含多少个 1 ,比如 5 的二进制表达是 101 ,其中包含 2 个 1

数据范围:输入的数字满足 0 ≤ n ≤ 231−1

输入描述:

输入为整型(十进制),只需兼容32-bit即可,如5、32

输出描述:

输出为字符串,如“2”、“1”

示例1

输入:5

输出:2

解题

import java.util.*;

public class Main {
    public static void main(String[] agrs) {
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        
        int count = 0;  // 记录1的个数
        for (; num > 0; num /= 2) {  // 短除法
            if (num % 2 == 1) {  // 奇数
                count++;
            }
        }
        System.out.print(count);
    }
}

KS33寻找奇数

描述

现在有一个长度为 n 的正整数序列,其中只有一种数值出现了奇数次,其他数值均出现偶数次,请你找出那个出现奇数次的数值。

数据范围:1 ≤ n ≤ 2×106

输入描述:

第一行:一个整数n,表示序列的长度。第二行:n个正整数ai,两个数中间以空格隔开。

输出描述:

一个数,即在序列中唯一出现奇数次的数值。

解题(法一:会超时)

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int str = sc.nextInt();
        String s;
        while((s = sc.nextLine()) != null) {
            String strs = sc.nextLine();
            String[] strArr = strs.split(" ");
            int remain = 0;
            for(int i = 0; i < strArr.length; i++) {
                // 出现偶数次的数在经过不断异或后一定为0,与0异或不改变数
                remain ^= Integer.parseInt(strArr[i]);
            }
            
            // 所以最后剩下的数就是出现过奇数次的数
            System.out.println(remain);
        }
    }
}

解题(法二:不会超时)

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String strN;
        while((strN = br.readLine()) != null) {
            String[] strArr = br.readLine().split(" ");
            int remain = 0;
            for(int i = 0; i < strArr.length; i++)
                // 出现偶数次的数在经过不断异或后一定为0,与0异或不改变数
                remain ^= Integer.parseInt(strArr[i]);
            // 所以最后剩下的数就是出现过奇数次的数
            System.out.println(remain);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小沐_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值