「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」
前言
每日一题,轻松解题
每日一题为刷题系列 每日刷一题LeetCode题,并且对题目进行分析,分享思路。
正文
:检查一个字符串是否可以打破另一个字符串
难度:中等
题目要求:
给你两个字符串 s1 和 s2 ,它们长度相等,请你检查是否存在一个 s1 的排列可以打破 s2 的一个排列,或者是否存在一个 s2 的排列可以打破 s1 的一个排列。
ps: 字符串 x 可以打破字符串 y (两者长度都为 n )需满足对于所有 i(在 0 到 n - 1 之间)都有 x[i] >= y[i](字典序意义下的顺序)。
分析题目:
两个一样长的字符串,改变顺序后,有一个字符串可以打破另一个字符串,“打破”在上面ps中解释了
举个例子
s1 = 'cba' / s2 = 'bdf' 这时候s1和s2无法相互打破,但是改变顺序后
// 改变后
s1 = 'abc' / s2 = 'bdf' 这时候s2的每一个字符都大于等于s1,就表示s2可以打破s1
// 这样改也行
s1 = 'cba' / s2 = 'fdb' 这时候s2的每一个字符都大于等于s1,就表示s2可以打破s1
只要其中的每一项都大于另一个字符串的对应每一项就成立,
:解题
理清思路:
这种题目属于需要一个成立与否的结果,而没有一个固定解,所以我们没办法用运算得出结果,因为结果是多样的,这时候还是用到贪心算法。
分析:
先将s1中的字符出现的次数全部记录下来
分两次遍历s2,分别找到离s2[i]字典顺序最近的s1中字母(大于等于、小于等于两个方向);
如果某一侧所有arr中元素都为0,则说明没法达到条件。
编辑代码:
1.首先定义一个函数,传入两个相同长度的字符串。将s1中的字符出现的次数全部记录下来
function strBreak (s1, s2) {
let arr = new Array(26).fill(0);
let str = 'abcdefghijklmnopqrstuvwxyz';
for (let i of s1) {
let index = str.indexOf(i);
arr[index] += 1;
}
console.log(arr);
};
- 定义一个数组arr 存放26个0,对应26个字母
- 定义一个str字符串为26个字母,用于判断s1和s2各个字母的个数
- for循环遍历s1,使用
indexOf获取对应字母的索引,并且让数组arr中对应字母的数字加一,
扩展:
arr.fill() //用一个固定值填充一个数组中从起始索引到终止索引内的全部元素
arr = [0,0,.....,0] //26个0
arr.fill(1) // 用1替换arr中全部内容
arr.fill(1,1,2) //第二个1 是从索引1 开始 到索引2 结束 也就是把arr[1]---arr[2]替换成1 不包括arr[2]
str = '123'
str.indexOf(1) // 返回1 在str 中的索引,也就是0
这个for循环可以获得什么 -- 举个例子
let s1 = 'abcd'
for .... //for循环上面有,不写一遍了
console.log(arr) -->
[
1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
] //最后得到的arr
这样就知道s1中包含什么字母,并且知道各有几个,存放在arr中
2.分两次遍历s2,分别找到离s2[i]字典顺序最近的s1中字母(大于等于、小于等于两个方向)
let arr1 = arr.slice();
let c1 = true;
for (let i of s2) {
// s1 >= s2
let startIndex = str.indexOf(i);
let j = startIndex;
for (; j < arr1.length; j++) {
if (arr1[j] > 0) {
arr1[j] -= 1;
break;
}
}
if (j === arr1.length) {
c1 = false;
break;
}
}
let c2 = true;
for (let i of s2) {
// s1 <= s2
let endIndex = str.indexOf(i);
let j = endIndex;
for (; j >= 0; j--) {
if (arr[j] > 0) {
arr[j] -= 1;
break;
}
}
if (j === -1) {
c2 = false;
break;
}
}
return c1 || c2;
- slice()的作用,复制一份arr给arr1
- 定义一个值,来存放是否存在s1打破s2字符串
- 循环判断是否s1总是大于s2,是则返回true,不是则返回false
3.合并代码,就完成了
总结
无论做什么分析最重要,其中我们分析了题目,分析了解题思路,其实在分析完解题思路后,代码其实就是很简单的事情了,养成习惯,无论做什么之前,都要进行分析,这样有助于你更快更好的完成这件事。