更多算法实现见:https://github.com/Erindcl/Daily-algorithm
1. 两数之和
- 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
- 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
思路:遍历数组,将数组的某个元素与在该元素后面的其他元素进行求和,将和与目标值进行比较,若相等则返回两元素的索引。代码如下:
var twoSum = function(nums, target) {
for(var i=0; i < nums.length; i++){
for(var j = i+1; j < nums.length; j++){
if(nums[i] + nums[j] == target){
return [i,j]
}
}
}
};
更好的实现:
var twoSum = function(nums, target) {
var map = {};
for(var i=0; i<nums.length;i++) {
if(map[target-nums[i]] != undefined) {
return [map[target-nums[i]],i];
} else {
map[nums[i]] = i;
}
}
};
26. 删除排序数组中的重复项
思路:从数组的第二个元素起,将数组的每个元素与他的前一个元素进行比较,若俩元素不相等则将当前比较元素从零开始存放在数组中,若两数相等则继续下一次循环。代码如下:
var removeDuplicates = function (A) {
if (A == null || A.length == 0) {
return 0;
}
var index = 1;
for (var i = 1; i < A.length; i++) {
if (A[i] != A[i-1])
{
A[index] = A[i];
index++;
}
}
return index;
};
27. 移除元素
- 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
- 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
- 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
代码如下:
var removeElement = function(nums, val) {
var index = 0;
for (var i = 0; i < nums.length; i++) {
if (nums[i] != val) {
nums[index] = nums[i];
index++;
}
}
nums = nums.slice(0,index);
return index;
};
更好的实现:
var removeElement = function(nums, val) {
for(let i = 0; i< nums.length; i++) {
if(nums[i] == val) {
nums.splice(i, 1)
i-- // 由于对原数组进行了修改,故需要把下标 往前移一位
}
}
};
35. 搜索插入位置
- 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
- 你可以假设数组中无重复元素。
思路:此处要分三种情况:插入位置在首部、中部、尾部。当插入位置在首部时,返回0;当插入位置在尾部时,返回数组长度。当插入位置在中部时,利用二分法查找将元素与插入元素进行比较确认插入的位置。代码如下:
var searchInsert = function(nums, target) {
if (nums.indexOf(target) != -1) { // 数组中存在目标元素
return nums.indexOf(target);
} else { // 数组中不存在目标元素 故需要找到插入的位置
var start = 0, end = nums.length - 1;
if (target < nums[start]) { // 插入位置在数组首部
return 0;
} else if (target > nums[end]) { // 插入位置在数组尾部
return nums.length;
} else { // 插入位置在数组内部
while (start < end - 1) { // 此处可采用普通遍历也可采用二分法遍历查找 但当数组元素相当多的时候 二分法查找效率更高 star与end到最后始终会想差一
var center = parseInt((start + end) / 2);
if (nums[center] > target) {
end = center;
} else if (nums[center] < target) {
start = center;
} else {
return center;
}
}
if (nums[end] >= target) {
return end;
} else {
return end - 1;
}
}
}
};
更好的实现:
var searchInsert = function(nums, target) {
let len = nums.length
if (len === 0) {
return 0
}
for (let i = 0; i < len; i++) {
let num = nums[i]
if (target <= num ) {
return i
}
}
return len
};
53. 最大子序和
- 给定一个整数数组
nums
,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
思路:设置一个变量存放元素序列相加的最大的和。将数组逐个进行相加,当加到某个元素时和变为了负数则当前和直接置零,每次循环中都将当前和与最大和进行比较,如果当前和较大,则将当前和设置为新的最大和。代码如下:
var maxSubArray = function(nums) {
if (nums.length == 0 || nums == null) { // 非空判断
return 0;
}
var maxSum = 0, currSum = 0;
nums.forEach(function (value,index,nums) {
currSum += value;
if (currSum < 0) { // 和小于0就直接置0
currSum = 0;
}
maxSum = (maxSum < currSum) ? currSum : maxSum;
});
if (maxSum == 0) {
return Math.max(...nums);
}
return maxSum;
};
更好的实现:
var maxSubArray = function (nums) {
let count = nums[0], maxCount = nums[0]
for (let i = 1; i < nums.length; i++) {
count = Math.max(count + nums[i], nums[i])
maxCount = Math.max(maxCount, count)
}
return maxCount
};