1、 生成不重复验证码
题目描述
根据指定的种子(不含重复字符),生成指定验证码个数的字符串数组,要求验证码不能有重复字符。返回值需要生成所有可能的排列,并按照字典顺序升序返回。
分析设计
一道DFS基础题,由于题目中说不含重复字符,所以不需要排序种子,直接遍历即可。同时,需要设置有一个vis标志用于判断该字符是否在本轮遍历中访问过。
代码实现
class Solution{ ArrayList<String> list = new ArrayList<>(); public String[] getVerificationCode(char[] seed, int size){ int n = seed.length; boolean[] vis = new boolean[n]; dfs(seed, n, vis, size, ""); Collections.sort(list); String[] ans = new String[list.size()]; for(int i = 0; i < list.size(); ++i){ ans[i] = list.get(i); } return ans; } public void dfs(char[] seed, int n, boolean[] vis, int size, String s){ if(s.length() == size){ list.add(s); return; } for(int i = 0; i < n; ++i){ if(vis[i]){ continue; } vis[i] = true; dfs(seed, n, vis, size, s + seed[i]); vis[i] = false; } } }
2、数猴王
题目描述
一群猴子需要选出猴***举规则是:给定一个数字,所有猴子排成一排按照顺序编号从1开始,然后猴子从队头按照顺序1、2、3...数数,数到给定的数字的猴子淘汰,每淘汰一个猴子,给定的数字加1,下一个猴子接着从1开始数,数到那个给定的数字就淘汰,到队尾后循环从队头接着数字数,直到剩下最后一只猴子就是猴王。
分析设计
很典型的一道“约瑟夫环”问题,主要考察的是循环的判断和处理。往常类似的题目是给定的数字不变,这道题目稍微进行了变形,但基本套路不变。
对于一个环来说,变化的下标是需要对环长做取余操作的,避免越界。
对于这类“约瑟夫环”问题,有很多大佬都有详细的解答,也探讨了数学公式的解答,我这里主要是模拟实现过程,不去考虑数学公式问题。
假设5个猴子,从1开始数数,假设第一轮中,数到3的猴子淘汰,则1->2->3->4->5变成了1->2->4->5;第二轮中,给定的数字由3变成4,则数到4的猴子淘汰,则1->2->4->5变成了1->4->5;第三轮中,给定的数字由4变成5,则数到5的猴子淘汰,则1->4->5变成了1->4;第四轮中,给定的数字由5变成6,则数到6的猴子淘汰,则1->4变成了1,返回结果。
每轮去掉的下标=(前一下标+当前轮次中给定的数字+环长)%环长
代码实现
class Solution{ public int doPermute(int M, int N){ ArrayList<Integer> list = new ArrayList<>(); for(int i = 1; i <= N; ++i){ list.add(i); } int index = 0; while(list.size() > 1){ index = (index + list.size() + M - 1) % list.size(); list.remove(index); M++; } return list.get(0); } }