问题描述:
输入:一个字符串;
操作:找出字符串中仅出现一次的第一个字符并返回;
输出:满足条件的字符;
示例:
输入: ‘abcefagebc’
输出:‘f’;
常规解法:
常规解法即使用双层循环嵌套,知道找到满足条件的字符直接返回,时间复杂度为O(n^2)
;
function findStr(str) {
var l = str.length;
var flag;
for (var i = 0; i < l; i++) {
flag = true;
for (var j = i+1; j < l; j++) {
if (str[j] == str[i]) {
flag = false;
break;
}
}
if (flag) {
return str[i];
}
}
return;
}
var str = "abcefagebc";
console.log(findStr(str));
更优的解法:
使用Hash表数据结构,使用空间复杂度换取时间复杂度,从而降低算法的时间复杂度为O(n);算法中map的key为输入字符串的字符,value是该字符在字符串中对应的索引;数组arr的key是索引,值为对应的字符在字符串中出现的次数;
function findChar (str) {
var map = {};
var arrIndex = 0;
finalIndex = -1;
var arr = new Array(str.length);
var l = str.length;
for (var i=0; i<l; i++) {
var char = str[i];
if (map[char] == undefined) {
map[char] = arrIndex++;
arr[map[char]] = 1;
} else {
var index = map[char];
arr[index]++;
}
}
for (var i=0; i<l; i++) {
if (arr[i] == 1) {
finalIndex = i;
break;
}
}
if (finalIndex !== -1) {
for (var key in map) {
if (map[key] === finalIndex) {
return key;
}
}
}
return;
}
另一解法:使用两个map;其中另一个记录每个元素在字符串中的索引, 出现一次记录索引,出现多次置为-1;
function findChar(s) {
var map = {};
var idx = {};
for(let i = 0, l = s.length; i < l; i++) {
if (map[s[i]] == undefined) {
map[s[i]] = 1;
idx[s[i]] = i;
} else {
map[s[i]]++;
idx[s[i]] = -1;
}
}
for (let i in idx) {
if (idx[i] > -1) {
return s[idx[i]];
}
}
}
参考文献:
- https://zhuanlan.zhihu.com/p/27828718