二分查找
利用哈希表记录很简单,无脑解
var twoSum = function(numbers, target) {
let map = new Map();
let len = numbers.length;
for(let i=0;i<len;i++){
if(map.has(target-numbers[i]))return [map.get(target-numbers[i]),i+1];
map.set(numbers[i],i+1);
}
};
尝试双指针
var twoSum = function(numbers, target) {
let len = numbers.length;
let i = 0;
let j = len-1;
while(i<j){
let l = numbers[i];
let r = numbers[j];
let sum = l+r;
if(sum==target)return [i+1,j+1];
else if (sum>target) {j--;}
else if(sum<target){i++;}
}
};
看到有序数组,想二分查找;
var twoSum = function(numbers, target) {
let len = numbers.length;
let start = 0;
let end = len-1;
while(1){
let mid = Math.floor(start+(end-start)/2);
if(numbers[start]+numbers[end]==target)return [start+1,end+1];
else if (numbers[start]+numbers[end]>target) {end = numbers[start]+numbers[mid]>target?mid:end-1;}
else if(numbers[start]+numbers[end]<target) {start = numbers[end]+numbers[mid]<target?mid:start+1;}
}
};
笨蛋方法 穷搜
var mySqrt = function(x) {
let res = 0;
for(let i = 0;i>=0;i++){
if(i*i<=x) {res = i;}
else{return res;}
}
};
二分法,要设置左右区间,和中间值三个参数。
var mySqrt = function(x) {
if(x==0)return 0;
if(x==1)return 1;
let r = x;
let mid = Math.floor(r/2);
let l = 0;
while(1){
if(mid*mid==x)return mid;
else if(mid*mid>x){
r = mid;
mid = Math.floor(l+(r-l)/2) ;
}
else{
if((mid+1)*(mid+1)>x){return mid;}
else {l = mid; mid =Math.floor(l+(r-l)/2) ;}
}
}
};
二分法一定要在一个闭区间中查找
写while(left <= right), 写right = middle - 1, 在区间[left, right]
var searchInsert = function(nums, target) {
//if(nums[0]>target)return 0;
//if(nums[nums.length-1]<target)return nums.length;
let r = nums.length-1;
let l = 0,ans = nums.length;
while(l<=r){
const mid = Math.floor(l+(r-l)/2);
if(nums[mid]==target){return mid;}
else if(nums[mid]<target){l = mid+1;}
else{r = mid-1;ans = mid;}
}
return ans;
};
哈希表
var intersect = function(nums1, nums2) {
let l1 = nums1.length;
let l2 = nums2.length;
let duan = l1>=l2?nums2:nums1;
let chang = l1>=l2?nums1:nums2;
let map = new Map();
let ans=[];
for(let i of duan){
if(map.has(i)){map.set(i,map.get(i)+1);}
else{map.set(i,1);}
}
// console.log(map);
for(let j of chang){
if(map.get(j)>0){
map.set(j,map.get(j)-1);
ans.push(j);}
}
//console.log(ans);
return ans;
};
排序+双指针
var intersect = function(nums1, nums2) {
let l1 = nums1.length-1;
nums1.sort(function(a,b){return a-b});
let l2 = nums2.length-1;
nums2.sort(function(a,b){return a-b});
let ans=[];
//console.log(nums1,nums2);
while(l1>=0&&l2>=0){
if(nums1[l1]>nums2[l2]){l1--;}
if(nums1[l1]==nums2[l2]){ans.push(nums2[l2]);l1--;l2--;}
if(nums1[l1]<nums2[l2]){l2--;}
//console.log(ans);
}
return ans;
};
双指针
var reverseString = function(s) {
let l = 0,r = s.length-1;
while(l<=r){
const temp = s[l];
s[l] = s[r];
s[r] = temp;
l++;r--;
}
return s;
};
var removeDuplicates = function(nums) {
let l = 0;r = 1;
while(r<nums.length&&nums.length>1){
if(nums[l]==nums[r]){r++;}
else{
l++;
nums[l]=nums[r];
r++;
}
}
nums = nums.slice(0,l+1);
return l+1;
};
var removeElement = function(nums, val) {
nums.sort(function(a,b){return a-b;});
let l=0,r=0;
while(r<nums.length){
if(val==nums[r]){r++;}
else{l++;r++;}
}
nums = nums.slice(l);
return l;
};
优化,把后面没用的移到前面去除数字,不用从头到尾遍历。
var removeElement = function(nums, val) {
let ans = nums.length;
for (let i = 0; i < ans;) {
if (nums[i] == val) {
nums[i] = nums[ans - 1];
ans--;
} else {
i++;
}
}
return ans;
};
字符串直接拆分
var strStr = function(haystack, needle) {
if(needle=='')return 0;
for(let i =0;i<haystack.length;i++){
if(haystack[i]==needle[0]){
if(haystack.slice(i,i+needle.length)==needle){return i;}
}
}
return -1;
};
KMP算法
var reverseVowels = function(s) {
let map = new Map([['a'],['e'],['i'],['o'],['u'],['A'],['E'],['I'],['O'],['U']]);
s = s.split('');
let l = 0,r = s.length-1;
while(l<r){
// console.log(s[l],s[r],s);
if(map.has(s[l])&&map.has(s[r])){const p = s[l]; s[l] = s[r];s[r] = p;l++;r--;}
if(!map.has(s[l])){l++;}
if(!map.has(s[r])){r--;}
}
return s.join('');
};
双指针
var isPalindrome = function(s) {
let l = 0,r = s.length-1;
while(l<r){
//console.log(s[l],s[r],/[A-Za-z0-9]/.test(s[l]));
if(/[A-Za-z0-9]/.test(s[l])&&/[A-Za-z0-9]/.test(s[r])){
if(s[l].toLowerCase()==s[r].toLowerCase()){l++;r--;}
else{return false;}
}
if(!/[A-Za-z0-9]/.test(s[l])){l++;}
if(!/[A-Za-z0-9]/.test(s[r])){r--;}
}
return true;
};
先删除杂余符号,称为字符串,反转比较。
var isPalindrome = function(s) {
let sNew = s.toLowerCase().match(/[a-z0-9]+/g);
if(!sNew)return true;
s1 = sNew.join('');
return s1==s1.split('').reverse().join('');
};
数组常用函数。
1.reverse(),反转数组的元素顺序;
2.join(连接字),数组拼接为字符串,直接用连接字连接;
3.slice(),选取数组的一部分,并返回一个新数组。
4.splice(),从数组中添加或删除元素。
5.map
字符串常用函数。
1.match(),查找找到一个或多个正则表达式的匹配。
2.replace(),在字符串中查找匹配的子串,并替换与正则表达式匹配的子串。
3.slice(),提取字符串的片断,并在新的字符串中返回被提取的部分。[ )
4.substring() ,方法用于提取字符串中介于两个指定下标之间的字符。
5.split(),把字符串分割为字符串数组。
6.Array.from(s),把字符串s转换为数组。
二进制位符号
& | 与 | 两个位都为1时,结果才为1 |
| | 或 | 两个位都为0时,结果才为0 |
^ | 异或 | 两个位相同为0,相异为1 |
~ | 取反 | 0变1,1变0 |
<< | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
>> | 右移 | 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |
加法:不进位(^)+进位(与,左移1)