时间:2020-05-11 岗位:开发(2020字节跳动校园招聘后端和客户端方向第三场考试)
4种操作:(1)增加;(2)删除;(3)输出;(4)回退;
(4)回退操作只对(1)(2)起作用;
StringBuilder 记录字符串,然后每次进行(1)/(2)操作就放入栈中;在(4)操作的时候将字符串更新为栈顶字符串;
package compitition.zijie;
import java.util.Scanner;
import java.util.Stack;
public class Main1{
public static void main(String[] args){
Scanner c = new Scanner(System.in);
int n = c.nextInt();
StringBuilder sb = new StringBuilder();
Stack<String> stack = new Stack<>();
while (n-- > 0) {
switch (c.nextInt()){
case 1 :
stack.push(sb.toString());
String s = c.next();
sb.append(s);
break;
case 2 :
stack.push(sb.toString());
int del = c.nextInt();
if(sb.length() < del){
sb = new StringBuilder();
}else{
sb.delete(sb.length()-del,sb.length());
}
break;
case 3 :
int print = c.nextInt();
System.out.println(sb.charAt(print-1));
break;
case 4 :
sb = new StringBuilder(stack.pop());
break;
}
}
c.close();
}
}
给定字符串s和字典;问字符串有几种解释方式;
字典中至少存在两个单词,且每个单词长度<20;
用Set装入字典,maxLen记录单词最大长度;
递归寻找从索引begin开始往后的maxLen长度的字符串是否在字典中,是则继续递归;
【数组越界错误!!!】(不知道为什么)
Set装入字典;dp状态:以i结尾的字符串的解释方法数目;
如果在[index-maxLen , index]
区间找到有单词在字典中,则更新当前dp[index]
;
转移方程:
如果Set包含s.substring(index+1-nowLen,index+1)
,则dp[index] += dp[index+1-nowLen-1];
package compitition.zijie;
// 【T2】回溯
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main2{
static long result = 0;
static int len = 0;
static int maxLen = 0;
public static void main(String[] args){
Scanner c = new Scanner(System.in);
String s = c.next();
len = s.length();
Set<String> set = new HashSet<>();
int n = c.nextInt();
while (n-- > 0){
String ss = c.next();
set.add(ss);
maxLen = Math.max(maxLen,ss.length());
}
c.close();
backtrack(s,0,set);
System.out.println(result);
}
private static void backtrack(String s, int begin,Set<String> set){
if(begin >= len){
result++;
result = result % 835672545;
return;
}
int nowLen = 1;
while(begin+nowLen <= len && nowLen <= maxLen){
String nowStr = s.substring(begin,begin+nowLen);
if(set.contains(nowStr)){
backtrack(s,begin+nowLen,set);
}
nowLen++;
}
}
}
package compitition.zijie;
//【T2】dp
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main2_2{
static int len = 0;
static int maxLen = 0;
public static void main(String[] args){
Scanner c = new Scanner(System.in);
String s = c.next();
len = s.length();
long[] dp = new long[len];
Set<String> set = new HashSet<>();
int n = c.nextInt();
while (n-- > 0){
String ss = c.next();
set.add(ss);
maxLen = Math.max(maxLen,ss.length());
}
c.close();
dp[0] = set.contains(s.substring(0,1))?1:0;
int index = 1;
while(index < len){
int nowLen = 1;
while(nowLen <= maxLen && index+1-nowLen >= 0){
String nowStr = s.substring(index+1-nowLen,index+1);
if(set.contains(nowStr)){
if(index+1-nowLen == 0){
dp[index]++;
}else{
dp[index] += dp[index+1-nowLen-1];
}
dp[index] = dp[index] % 835672545;
}
nowLen++;
}
index++;
}
System.out.println(dp[len-1] % 835672545);
}
}
给出n只袜子的颜色;给出m天,每天要穿的两只袜子的索引;求满足每天两只袜子同色时,最小的改变袜子颜色次数(染袜子次数);
并查集合并n个索引,分类成len个集合;对每个集合,求集合的元素个数(总袜子数量)和已有的最大单个颜色数目(该集合中不需要染色的袜子个数);
package compitition.zijie;
import java.util.*;
public class Main3{
public static void main(String[] args){
Scanner c = new Scanner(System.in);
int n = c.nextInt();
int m = c.nextInt();
int[] nums = new int[n];
for(int i=0;i<n;i++){
nums[i] = c.nextInt();
}
//一共有n个袜子
UnionFindSet uset = new UnionFindSet(n);
//将n个袜子合并
while (m-- > 0){
int a_i = c.nextInt()-1;
int b_i = c.nextInt()-1;
//这两个序号的袜子是要变成一个颜色哦
uset.union(a_i,b_i);
}
c.close();
List<List<Integer>> listAll = uset.fenzu();
int result = 0;
for(List<Integer> list : listAll){
int max = 0;
Map<Integer,Integer> map = new HashMap<>();
for(int index : list){
int nowNums = map.getOrDefault(nums[index],0)+1;
map.put(nums[index],nowNums);
max = Math.max(max,nowNums);
}
result += list.size() - max;
}
System.out.println(result);
}
}
class UnionFindSet {
int[] parents;//存放父节点下标
int[] ranks;//表示当前的秩(深度)
int len;
//初始化一个n大小的并查集结构
public UnionFindSet(int n) {
len = n;
parents = new int[n];
for (int i = 0; i < n; i++) {
parents[i] = i;
}
ranks = new int[n];
}
//优化1
//查找当前节点的父亲,与此同时有【路径压缩】优化
public int find(int x) {
if (x != parents[x]) {//如果x不是父节点
parents[x] = find(parents[x]);//那么它的父节点就是根节点
}
return parents[x];
}
//合并两个节点,以其中一个节点作为父亲,包含【按秩合并】优化
public void union(int x, int y) {
x = find(x);//找x的父节点
y = find(y);
if (x == y) return;
//直接合并两个父节点
if (ranks[x] > ranks[y]) {
parents[y] = x;
} else if (ranks[x] < ranks[y]) {
parents[x] = y;
} else {
parents[x] = y;
ranks[y]++;
}
}
//返回所有的分组,只有root节点对应的list才不为空
public List<List<Integer>> fenzu() {
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < len; i++) {
result.add(new ArrayList<>());//增加n个list
}
for (int i = 0; i < len; i++) {
result.get(find(i)).add(i);//根节点的那个list加上i
}
return result;
}
}
给一个字符串s
,有两种操作(1)改变s[i]
字符为c
;(2)查询[left , right]
中不同字符的个数;
package compitition.zijie;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main4{
public static void main(String[] args){
Scanner c = new Scanner(System.in);
char[] str = c.next().toCharArray();
//System.out.println(Arrays.toString(dp));
int n = c.nextInt();
while(n-->0){
int caozuo = c.nextInt();
switch (caozuo){
case 1 ://变换
int index = c.nextInt()-1;
String newChar = c.next();
str[index] = newChar.charAt(0);
break;
case 2 ://查询
int begin = c.nextInt()-1;
int end = c.nextInt()-1;
int result = 0;
Set<Character> set = new HashSet<>();
for(int i=begin;i<=end;i++){
set.add(str[i]);
}
System.out.println(set.size());
break;
}
}
c.close();
}
}