LeetCode 384. 打乱数组 / 859. 亲密字符串/ 423. 从英文中重建数字
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 384. 打乱数组 / 859. 亲密字符串/ 423. 从英文中重建数字相关的知识,希望对你有一定的参考价值。
384. 打乱数组
2021.11.22 每日一题
题目描述
给你一个整数数组 nums ,设计算法来打乱一个没有重复元素的数组。
实现 Solution class:
Solution(int[] nums) 使用整数数组 nums 初始化对象
int[] reset() 重设数组到它的初始状态并返回
int[] shuffle() 返回数组随机打乱后的结果
示例:
输入
[“Solution”, “shuffle”, “reset”, “shuffle”]
[[[1, 2, 3]], [], [], []]
输出
[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]
解释
Solution solution = new Solution([1, 2, 3]);
solution.shuffle(); // 打乱数组 [1,2,3] 并返回结果。任何 [1,2,3]的排列返回的概率应该相同。例如,返回 [3, 1, 2]
solution.reset(); // 重设数组到它的初始状态 [1, 2, 3] 。返回 [1, 2, 3]
solution.shuffle(); // 随机返回数组 [1, 2, 3] 打乱后的结果。例如,返回 [1, 3, 2]
提示:
1 <= nums.length <= 200
-10^6 <= nums[i] <= 10^6
nums 中的所有元素都是 唯一的
最多可以调用 5 * 10^4 次 reset 和 shuffle
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shuffle-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
对于n个数,用的随机思路是先产生一个n以内的随机数idx,然后idx与0处的数组元素交换位置,然后再产生n - 1 内的随机数idx,idx + 1 与1位置交换,以此类推
原来叫 Fisher-Yates 洗牌算法
System.arraycopy(原数组,起始下标,要复制的数组,起始下标,长度)
class Solution
int[] remain;
int[] shuff;
int l;
public Solution(int[] nums)
l = nums.length;
remain = new int[l];
for(int i = 0; i < l; i++)
remain[i] = nums[i];
shuff = nums;
public int[] reset()
return remain;
public int[] shuffle()
Random rd = new Random();
for(int i = l; i > 0; i--)
int idx = rd.nextInt(i);
int temp = shuff[idx + l - i];
shuff[idx + l - i] = shuff[l - i];
shuff[l - i] = temp;
return shuff;
/**
* Your Solution object will be instantiated and called as such:
* Solution obj = new Solution(nums);
* int[] param_1 = obj.reset();
* int[] param_2 = obj.shuffle();
*/
859. 亲密字符串
2021.11.23 每日一题
题目描述
给你两个字符串 s 和 goal ,只要我们可以通过交换 s 中的两个字母得到与 goal 相等的结果,就返回 true ;否则返回 false 。
交换字母的定义是:取两个下标 i 和 j (下标从 0 开始)且满足 i != j ,接着交换 s[i] 和 s[j] 处的字符。
例如,在 “abcd” 中交换下标 0 和下标 2 的元素可以生成 “cbad” 。
示例 1:
输入:s = “ab”, goal = “ba”
输出:true
解释:你可以交换 s[0] = ‘a’ 和 s[1] = ‘b’ 生成 “ba”,此时 s 和 goal 相等。
示例 2:
输入:s = “ab”, goal = “ab”
输出:false
解释:你只能交换 s[0] = ‘a’ 和 s[1] = ‘b’ 生成 “ba”,此时 s 和 goal 不相等。
示例 3:
输入:s = “aa”, goal = “aa”
输出:true
解释:你可以交换 s[0] = ‘a’ 和 s[1] = ‘a’ 生成 “aa”,此时 s 和 goal 相等。
示例 4:
输入:s = “aaaaaaabc”, goal = “aaaaaaacb”
输出:true
提示:
1 <= s.length, goal.length <= 2 * 10^4
s 和 goal 由小写英文字母组成
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/buddy-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
看题目要求是需要有两个能交换的位置,即使是相同字母交换也可以
class Solution
public boolean buddyStrings(String s, String goal)
//很显然,题目要求是交换一次
//那么就只能有两处不同并且是对应的
int ls = s.length();
int lg = goal.length();
int[] cnt = new int[26];
if(ls != lg)
return false;
int count = 0;
int idx = -1;
for(int i = 0; i < ls; i++)
cnt[s.charAt(i) - 'a']++;
if(s.charAt(i) != goal.charAt(i))
count++;
if(count == 1)
idx = i;
else if(count == 2)
if(s.charAt(i) != goal.charAt(idx) || s.charAt(idx) != goal.charAt(i))
return false;
else if(count > 2)
return false;
if(count == 0)
for(int i = 0; i < 26; i++)
if(cnt[i] > 1)
return true;
return false;
if(count == 1)
return false;
return true;
423. 从英文中重建数字
2021.11.24 每日一题
题目描述
给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)。按 升序 返回原始的数字。
示例 1:
输入:s = “owoztneoer”
输出:“012”
示例 2:
输入:s = “fviefuro”
输出:“45”
提示:
1 <= s.length <= 10^5
s[i] 为 [“e”,“g”,“f”,“i”,“h”,“o”,“n”,“s”,“r”,“u”,“t”,“w”,“v”,“x”,“z”] 这些字符之一
s 保证是一个符合题目要求的字符串
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reconstruct-original-digits-from-english
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
我想到的是挑出每一个数字中独特的字符,然后通过这个字符判断这个数字有几个
不过好像效率有点低
看了下解答,都差不多一个意思,用数组统计字母的话要快点,就这样了
class Solution
public String originalDigits(String s)
//"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine";
//我想到一个思路就是看哪个字母是唯一的,然后从这里下手来拆解这个字符串
//例如,g字母只有8中有,u只有4中有,z只有0中有,x只有6中有,w只有2中有,所以先拆解这无五个字符串
//拆解完这三个字符串以后,发现,f只有5中有了,r只有3中有,o只有1中有,s只有7中有
//最后就剩下9了,可行
Map<Character, Integer> map = new HashMap<>();
for(char c : s.toCharArray())
map.put(c, map.getOrDefault(c, 0) + 1);
int[] count = new int[10];
//先看第一轮g,u,z,x,w
count[0] = map.getOrDefault('z', 0);
//map.put('e', map.getOrDefault('e', 0) - count[0]);
map.put('r', map.getOrDefault('r', 0) - count[0]);
map.put('o', map.getOrDefault('o', 0) - count[0]);
count[2] = map.getOrDefault('w', 0);
//map.put('t', map.getOrDefault('t', 0) - count[2]);
map.put('o', map.getOrDefault('o', 0) - count[2]);
count[4] = map.getOrDefault('u', 0);
map.put('f', map.getOrDefault('f', 0) - count[4]);
map.put('o', map.getOrDefault('o', 0) - count[4]);
map.put('r', map.getOrDefault('r', 0) - count[4]);
count[6] = map.getOrDefault('x', 0);
map.put('s', map.getOrDefault('s', 0) - count[6]);
map.put('i', map.getOrDefault('i', 0) - count[6]);
count[8] = map.getOrDefault('g', 0);
//map.put('e', map.getOrDefault('e', 0) - count[8]);
map.put('i', map.getOrDefault('i', 0) - count[8]);
//map.put('h', map.getOrDefault('h', 0) - count[8]);
//map.put('t', map.getOrDefault('t', 0) - count[8]);
//第二轮,f,r,o,s
count[1] = map.getOrDefault('o', 0);
count[3] = map.getOrDefault('r', 0);
count[5] = map.getOrDefault('f', 0);
map.put('i', map.getOrDefault('i', 0) - count[5]);
count[7] = map.getOrDefault('s', 0);
count[9] = map.getOrDefault('i', 0);
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 10; i++)
for(int j = 0; j < count[i]; j++)
sb.append(i + "");
return sb.toString();
以上是关于LeetCode 384. 打乱数组 / 859. 亲密字符串/ 423. 从英文中重建数字的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode 384 打乱数组[洗牌] HERODING的LeetCode之路