这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战
第一个只出现一次的字符
剑指Offer 50.第一个只出现一次的字符
难度:简单
在字符串s中找出第一个只出现一次的字符。如果没有,返回一个单空格。s只包含小写字母。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
限制: 0 <= s的长度 <= 50000
题解
法一 使用api函数
使用indexOf和lastIndexOf巧妙解决问题。
/**
* @param {string} s
* @return {character}
*/
var firstUniqChar = function (s) {
for (let x of s) {
if (s.indexOf(x) === s.lastIndexOf(x)) {
return x;
}
};
return ' ';
};
法二 哈希表
步骤:
- 对字符串进行循环,如果字符第一次出现,则在哈希表中对其置1,如果不是第一次出现的话则进行累加。
- 遍历哈希表,返回第一个出现次数为1的字符。
var firstUniqChar = function (s) {
if(!s) return ' ';
let dic = new Map();
for (let c of s) {
if (dic.has(c)) {
dic.set(c, dic.get(c) + 1)
} else {
dic.set(c, 1);
}
}
for (let x of dic.keys()) {
if (dic.get(x) === 1) {
return x;
}
}
return ' ';
};
- 时间复杂度:O()
- 空间复杂度:O()
数组中的逆序对
剑指Offer 51.数组中对逆序对
难度:困难
在数组的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例1:
输入: [7,5,6,4]
输出: 5
限制:0 <= 数组长度 <= 50000
题解
法一 暴力法
两层for循环去检查是否为逆序对。
var reversePairs = function (nums) {
let sum = 0;
const len = nums.length;
for (let i = 0; i < len; i++) {
for (let j = i + 1; j < len; j++) {
nums[i] > nums[j] && sum++;
}
}
return sum;
}
- 时间复杂度:O()
- 空间复杂度:O()
法二 归并排序
能够看到非常明显的阶段排序结果的算法就是归并排序,采用分而治之的思想:
- 将数组不断的进行一拆二,拆到每个数组中只有一个元素为止
- 对每个数组两两进行合并,其中每个数组内都是有序的
对于本题:
先设置一个sum来记录逆序对个数,采用归并排序的方式,在合并时,设置i和j分别对应两个合并数组的左部分left和右部分right,当left[i] > right[j]
时说明当前[i, left.length]的值均大于right[j],因此均可以作为逆序对,故sum += left.length - i
。
var reversePairs = function (nums) {
let sum = 0;
mergeSort(nums);
return sum;
function mergeSort(nums) {
if (nums.length < 2) return nums;
const mid = Math.floor(nums.length / 2);
let left = nums.slice(0, mid);
let right = nums.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
let res = [];
let lLen = left.length;
let rLen = right.length;
let Len = lLen + rLen;
for (let index = 0, i = 0, j = 0; index < Len; index++) {
if (i >= lLen) res[index] = right[j++]; // i遍历完了
else if (j >= rLen) res[index] = left[i++]; // j遍历完了
else if (left[i] <= right[j]) res[index] = left[i++];
else {
res[index] = right[j++];
sum += lLen - i;
}
}
return res;
}
}
- 时间复杂度:O()
- 空间复杂度:O()
坚持每日一练!前端小萌新一枚,希望能点个赞
哇~