【LeetCode与《代码随想录》】数组篇:做题笔记与总结-Java版

代码随想录地址
是学习过程中的笔记!图来自代码随想录。

文章目录

    • 理论
    • 题目
      • 704. 二分查找
      • 35. 搜索插入位置
      • 34. 在排序数组中查找元素的第一个和最后一个位置
      • 69. x 的平方根
      • 367.有效的完全平方数

理论

数组是存放在连续内存空间上的相同类型数据的集合。

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的。

因此,我们在添加和删除元素的时候要移动数组内的其他元素。

注意:关于C++的vector,它是容器,不是数组——数组里的元素只能覆盖,不能删除

二维数组在内存的空间地址也是连续的。

题目

704. 二分查找

704. 二分查找

这里有两种方法:左闭右闭区间 和 左闭右开区间。
个人感觉可以左闭右开,也就是右区间取不到的原因是除法是向下取整的,所以要保持右区间大一些。

左闭右闭相关理论:
【LeetCode与《代码随想录》】数组篇:做题笔记与总结-Java版_第1张图片

class Solution {
public:
    int search(vector<int>& nums, int target) {
    int l=0,r=nums.size()-1;
    int mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(nums[mid]>target) r=mid-1;//不在mid处
        else if(nums[mid]<target) l=mid+1;
        else return mid;//等于且找到了
    }
    return -1;
    }
};

左闭右开相关理论:
【LeetCode与《代码随想录》】数组篇:做题笔记与总结-Java版_第2张图片

class Solution {
public:
    int search(vector<int>& nums, int target) {
    int l=0,r=nums.size();
    int mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if(nums[mid]>target) r=mid;//不在mid处,但右区间取不到,所以等于mid
        else if(nums[mid]<target) l=mid+1;//不在mid处,左区间可以取到,所以等于mid+1
        else return mid;//等于且找到了
    }
    return -1;
    }
};

一些更难的二分拓展

35. 搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
    int l=0,r=nums.size()-1;
    int mid;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(nums[mid]>target) r=mid-1;
        else if(nums[mid]<target) l=mid+1;
        else return mid;//找到了
    }
    //没找到:应该的位置是l的位置:分为r主动往左走(t太小)和l主动往右走的情况(t太大)
    //r往左走,nums[r]
    //l往右走,nums[l]>t,是第一个大于t的位置——所以答案是l所在的位置
    return l;
    }
};

34. 在排序数组中查找元素的第一个和最后一个位置

34. 在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
    //找第一个等于t的位置和最后一个等于t的位置
    
    vector<int>ans;
    //数组为空&&左右边界
    if(nums.size()==0||nums.back()<target||nums[0]>target)  return {-1,-1};  

    //找最后一个小于t
    int ans1,ans2;
    int l=0,r=nums.size()-1,mid,temp=0;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(nums[mid]>=target) r=mid-1;
        else l=mid+1;   //这里mid+1不怕超过 因为每次存的答案是r     
        ans1=r;
        temp++;
    }
    if(!temp) return {-1,-1};
    
    //找第一个大于t
    l=0,r=nums.size()-1,temp=0;
    while(l<=r)
    {
        mid=(l+r)/2;
        if(nums[mid]<=target) l=mid+1;
        else  r=mid-1;      
        ans2=l;
        temp++;
    }
    if(!temp) return {-1,-1};
    
    if(ans2-ans1>1) return {ans1+1,ans2-1};

    return {-1,-1};
    }
};

69. x 的平方根

69. x 的平方根

class Solution {
public:
    int mySqrt(int x) {
    int l=0,r=46342;
    int mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if((long long)mid*mid>x) r=mid;
        else if((long long)mid*mid<x) l=mid;
        else return mid;      
        if(r-l==1) return l;
    }

    return 0;//其实绝对不会到这一步
    }
};

367.有效的完全平方数

367.有效的完全平方数

方法一:二分

class Solution {
public:
    bool isPerfectSquare(int num) {
    int l=1,r=46342;
    int mid;
    while(l<=r)
    {       
        mid=(l+r)/2;
        if((long long)mid*mid>num) r=mid-1;
        else if((long long)mid*mid<num) l=mid+1;
        else return true; 
    }
    return false;
    }
};

方法二:数学。

(n+1)2=n2+2n+1

class Solution {
public:
    bool isPerfectSquare(int num) {
    if(num==1) return true;
    int x=1;
    num--;
    while(num>0)
    {
        num-=2*x+1;
        x++;
    }
    if(num==0) return true;
    else return false;
    }
};

你可能感兴趣的:(leetcode,java,算法)