最近跟着代码随想录刷算法题有点入迷,不知道大学在干嘛,都没怎么刷过题。。。
接下来对近段时间刷的数组题做一个总结,全部都是Javascript写的。
704.二分查找
关键词:有序数组
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let left =0, right= nums.length-1;
while(left<=right)
{
let mid = left+Math.floor((right-left)/2);
if (target<nums[mid])
right= mid-1;
else if (target>nums[mid])
left = mid+1;
else
return mid;
}
return -1;
};
注意左右边界,左闭右闭就说明left=right是有意义的,mid是返回值
35.搜索插入位置
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let left =0,right=nums.length-1;
while(left<=right){
let mid=left+Math.floor((right-left)/2)
if(nums[mid]<target)
left=mid+1;
else if(nums[mid]>target)
right=mid-1;
else
return mid;
}
return right+1;
};
34.在排序数组中查找元素的第一个和最后一个位置
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
const GetLeftBorder=(nums,target)=>{
let left=0,right=nums.length-1;
let LeftBorder=-2
while(left<=right){
let mid=left+Math.floor((right-left)/2);
if(nums[mid]<target)
left=mid+1;
else
right=mid-1;
LeftBorder=right
}
return LeftBorder
}
const GetRightBorder=(nums,target)=>{
let left=0,right=nums.length-1;
let RightBorder=-2
while(left<=right){
let mid=left+Math.floor((right-left)/2);
if(nums[mid]>target)
right=mid-1;
else
left=mid+1;
RightBorder =left
}
return RightBorder
}
let LeftBorder=GetLeftBorder(nums,target)
let RightBorder=GetRightBorder(nums,target)
if (LeftBorder===-2 || RightBorder ===-2) //情况一
return [-1,-1];
if (RightBorder-LeftBorder>1) //情况三
return [LeftBorder+1,RightBorder-1];
return [-1,-1]; //情况二
};
找到左边界和有边界,有三个情况
寻找target在数组里的左右边界,有如下三种情况:
情况一:target 在数组范围的右边或者左边,例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}
情况二:target 在数组范围中,且数组中不存在target,例如数组{3,6,7},target为5,此时应该返回{-1, -1}
情况三:target 在数组范围中,且数组中存在target,例如数组{3,6,7},target为6,此时应该返回{1, 1}
69.x的平方根
/**
* @param {number} x
* @return {number}
*/
var mySqrt = function(x) {
let left=1,right=x/2+1;
while(left<=right){
let mid=left+Math.floor((right-left)/2)
if (mid<x/mid)
left = mid+1;
else if (mid>x/mid)
right = mid -1;
else
return mid;
}
return right;
}
367.有效的完全平方数
/**
* @param {number} num
* @return {boolean}
*/
var isPerfectSquare = function(num) {
let left=1,right=num/2+1;
while(left<=right){
let mid=left+Math.floor((right-left)/2);
if(mid<num/mid)
left=mid+1;
else if(mid>num/mid)
right=mid-1;
else
return true;
}
return false
};
27.移除元素
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let k=0;
for(let i=0;i<nums.length;i++){
if(nums[i]!=val)
nums[k++]=nums[i]
}
return k;
};
利用双指针的思想
26. 删除有序数组中的重复项
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
let k=0;
for(let i=0;i<nums.length;i++)
if(nums[i]!=nums[i+1])
{
nums[k++]=nums[i]
}
return k;
};
283. 移动零
/**
* @param {number[]} nums
* @return {void} Do not return anything, modify nums in-place instead.
*/
var moveZeroes = function(nums) {
let k=0;
length=nums.length
for(let i=0;i<length;i++){
if(nums[i]!=0){
nums[k++]=nums[i];
}
}
for (let j=length-1;j>=k;j--){
nums[j]=0;
}
return nums
};
就先把非0的存到k指针里面,然后剩下的是0放在尾部即可
977.有序数组的平方
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
let k=0;
for(let i=0;i<nums.length;i++){
nums[k++]=nums[i]*nums[i];
}
for(let i=0;i<nums.length-1;i++){
for(let j=i+1;j<nums.length;j++){
if (nums[j]<nums[i]){
temp=nums[i]
nums[i]=nums[j]
nums[j]=temp
}
}
}
return nums
};
我的理解这道题更像是先用一个指针存平方后的值,然后再排序,用的排序方法是选择排序
203. 移除链表元素
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
const res = new ListNode(0,head);
cur = res;
while (cur.next){
if(cur.next.val==val)
{
cur.next=cur.next.next;
continue;
}
cur=cur.next;
}
return res.next;
};
定义虚拟头节点
206. 反转链表
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
if(!head||!head.next) return head;
let temp = null, pre = null,cur=head;
while(cur){
temp=cur.next; //存cur指针的下一个节点
cur.next= pre;//反转
pre=cur; //更新
cur=temp;
}
return pre;
};
24. 两两交换链表中的节点
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var swapPairs = function(head) {
const ret = new ListNode(0,head);
cur=ret;
while(cur.next && cur.next.next){
temp1=cur.next;
temp2=cur.next.next.next;
cur.next=cur.next.next; //步骤一
cur.next.next=temp1; //步骤二
cur.next.next.next= temp2; //步骤三
cur=cur.next.next; //更新
}
return ret.next;
};
19. 删除链表的倒数第 N 个结点
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
const ret=new ListNode(0,head);
let slow=ret,fast=ret;
let i=0;
while(i<n+1){
fast=fast.next;
i++
}
while(fast){
slow=slow.next;
fast=fast.next;
}
slow.next=slow.next.next
return ret.next
};