/**
* @param {character[]} s
* @return {void} Do not return anything, modify s in-place instead.
*/
var reverseString = function(s) {
for(let i=0;i<(s.length>>1);i++) {
let k=s[i];
s[i]=s[s.length-i-1];
s[s.length-i-1]=k;
}
};
/**
* @param {string} s
* @param {number} k
* @return {string}
*/
var reverse = function(s) {
let str = new String();
for(let i=s.length-1;i>=0;i--){
str+=s[i];
}
return str;
}
var reverseStr = function(s, k) {
let a = new Array();
let num=0;
for(let i=0;i<s.length;i++) {
++num;
if(num==k) {
a.push(reverse(s.slice(i+1-num,i+1)));
}
else if(num==2*k) {
a.push(s.slice(i+1-num+k,i+1));
num=0;
}
}
if(num<k) {
a.push(reverse(s.slice(s.length-num,s.length)));
}
else if(num>k&&num<2*k) {
a.push(s.slice(s.length-num+k,s.length));
}
let result = new String();
for(let i of a) {
result+=i;
}
return result;
};
/**
* @param {string} s
* @return {string}
*/
var replaceSpace = function(s) {
let a = new Array();
for(let i of s) {
if(i!==' ') {
a.push(i);
}
else {
a.push('%20');
}
}
return a.join('');
};
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
let a = new Array();
let news = s.trim();
let start=-1;
for(let i=0;i<news.length;i++) {
if(news[i]==' '&&news[i+1]!==' ') {
a.push(news.slice(start+1,i).trim());
start=i;
}
if(i===news.length-1) {
a.push(news.slice(start+1,i+1));
}
}
let result = new String();
a.reverse();
result=a.join(' ');
return result;
};
/**
* @param {string} s
* @param {number} n
* @return {string}
*/
var reverseLeftWords = function(s, n) {
let a = new Array();
for(let i=n;i<s.length;i++) {
a.push(s[i]);
}
for(let i=0;i<n;i++) {
a.push(s[i]);
}
let result = new String();
result=a.join('');
return result;
};
kmp忘记了,主要是next数组的写法。回顾了一下。这个视频讲的很清楚
帮你把KMP算法学个通透!
帮你把KMP算法学个通透!(求next数组代码篇)
/**
* @param {string} haystack
* @param {string} needle
* @return {number}
*/
var strStr = function(haystack, needle) {
const findnext = function(needle) {
let next = new Array();//数组里存的是截至到各个位置之前的相同前后缀长度,也就是在比较的过程中,前面都匹配上了,当前位不匹配了,子串指针应该调整到的位置
let i,j=0;//j表示前缀末尾
next.push(0);
for(i=1;i<needle.length;i++) {//i表示后缀末尾
while(j>=1 && needle[i]!==needle[j]) {
j=next[j-1]//如果j和i位不相同,j退回他的上一位,他的上一位保存的正是上一次的相同前后缀
}
if(needle[i]===needle[j]) {
j++; //同时j也表示相同前后缀长度
}
next.push(j);
}
return next;
}
let next = findnext(needle);
let p=0;
let q=0;
while(p<haystack.length) {
if(haystack[p]!==needle[q]) {
if(q>=1) {
q=next[q-1];
}
else{
p++;
}
}
else{
p++;
q++;
}
if(q===needle.length) {
return p-q;
}
}
return -1;
};
459. 重复的子字符串
最小重复子串和最长前后缀的关系:
/**
* @param {string} s
* @return {boolean}
*/
var repeatedSubstringPattern = function(s) {
let i,j;
j=0;
let next = [];
next.push(0);
for(i=1;i<s.length;i++) {
while(j>=1 && s[i]!==s[j]) {
j=next[j-1];
}
if(s[i]===s[j]) {
j++;
}
next.push(j);
}
if(next[s.length-1]!==0 && s.length%(s.length-next[s.length-1])===0) {
return true;
}
else {
return false;
}
};
中心扩散法:以某个V为起点,先找和V相同值的左右邻居(它们之间都是V),再以左右邻居(L、R)为起点向两边扩散。
定义两个指针,一个left,一个right,指向V的左右位置
先比较两个指针是否和当前位置的V的值相同,左边有一个相等,left就-1,右边有一个相等,right就+1
与v相同的值的所有连续子串都是回文字符串(如:a、aa、aaa)
再比较左右邻居(两个指针)是否相等,相等left-1,right+1,
直到比到不相等为止,可以break中止,查看他是否是最长的回文子串。
var longestPalindrome = function(s) {
let arr = s.split('');
let res='';
for(let i=0;i<arr.length;i++) {
let l=i-1;
let r=i+1;
while(l>=0) {
if(arr[l]===arr[i]) {
l--;
}
else break;
}
while(r<=arr.length-1) {
if(arr[r]===arr[i]) {
r++;
}
else break;
}
while(l>=0 && r<=arr.length-1) {
if(arr[l]===arr[r]) {
l--;
r++;
}
else break;
}
if(r-l-1 >res.length) {
res=s.slice(l+1,r);
}
}
return res;
};