一,对数组的新认识  

    不同编程语言的内存管理是不一样的,以C++为例,在C++中二维数组是连续分布的。而对于Java来说,二维数组不是连续分布的。

思考:

cout << &array[0][0] << " " << &array[0][1] << " " << &array[0][2] << endl;

    对C++来说,可以通过取址运算符来获取二维数组的具体的地址值,那么Java如何获取array[0][1]的地址呢?

二,704.二分查找

二分查找也叫做折半查找 ,元素必须是有序的,从小到大,或者从大到小都是可以的。

用给定值先与中间结点比较。比较完之后有三种情况:

  • 相等
    说明找到了
  • 要查找的数据比中间节点小
    说明要查找的数字在中间节点左边
  • 要查找的数据比中间节点大
    说明要查找的数字在中间节点右边


题目来源:力扣


  对于左闭右闭区间,代码如下

class Solution {
    public int search(int[] nums, int target) {
    int left=0;
    int right=nums.length-1;
    while(left<=right)
    {
      int  mid=left+(right-left)/2;
        if(target>nums[mid])
          left=mid+1;
        if(target<nums[mid])
        right=mid-1;
         if(target==nums[mid])
        return mid; 
    }
    return -1;
    }
}

遇到的问题:

对于左闭右开的代码写不出来,不太理解

对于左闭右开区间,代码如下

class Solution {
    public int search(int[] nums, int target) {
    int left=0;
    int right=nums.length;
    while(left<right)
    {
      int  mid=left+((right-left)>>1);
      if(target>nums[mid])
          left=mid+1;
      else if(target<nums[mid])
        right=mid;
     else
        return mid; 
    }
    return -1;
    }
}

左闭右开和左闭右闭区间对比(三处不同)

左闭右闭                                         
int right=nums.length-1;  
while(left<=right)   

right=mid-1;  

左闭右开

int right=nums.length;              

while(left<right)                       

right=mid;

 同时,代码中舍弃了

mid=(left+right)/2的用法,采用

int mid=left+((right-left)>>1);int mid=left+((right-left)/2);

 两者都是为了防止溢出,相关文章和其他方法:

看完微软大神写的求平均值代码,我意识到自己还是too young了

int  mid=left/2+right/2+(left&right&1);
int  mid=(left&right)+(left^right)/2;

在while循环前,可以加上如下句子:防止多次循环运算

// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }

三,27.移除元素




力扣

1.暴力解法代码:时间复杂度O(

JAVA移除数组元素方法 java数组移除指定元素_数据结构

),空间复杂度O(n)

数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。

class Solution {
    public int removeElement(int[] nums, int val) {
        int size=nums.length;
     for(int i=0;i<size;i++)
     {
         if(nums[i]==val){
         for(int j=i+1;j<size;j++)
         {
           nums[j-1]=nums[j];
         }
         
         i--;
         size --;
         }
     }
     return size;
    }
}

JAVA移除数组元素方法 java数组移除指定元素_JAVA移除数组元素方法_02

对于边界情况,也是可以改一下的:

for(int j=i+1;j<size;j++)
         {
           nums[j-1]=nums[j];
         }

可改为:

for(int j=i;j<size-1;j++)
         {
           nums[j]=nums[j+1];
         }

 2.快慢双指针法:

指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置
class Solution {
    public int removeElement(int[] nums, int val) {
      int fast=0;
      int slow=0;
      for(fast=0;fast<nums.length;fast++)
      {
      if(val!=nums[fast])
      {
          nums[slow]=nums[fast];
          slow++;
      }
      }
      return slow;
    }
}
nums[slow]=nums[fast];
          slow++;

也可一步到位:

nums[slow++]=nums[fast];

同时注意,是直接返回slow,而不是slow+1;

JAVA移除数组元素方法 java数组移除指定元素_力扣_03




JAVA移除数组元素方法 java数组移除指定元素_力扣_04



双向双指针法:

class Solution {
    public int removeElement(int[] nums, int val) {
     int left=0;
     int right=nums.length-1;
     while(right>=0&&nums[right]==val)  right--;
     while(left<=right)
     {
         if(nums[left]==val)
         {
             nums[left]=nums[right];
             right--;
         }
         left++;
          while(right>=0&&nums[right]==val)  right--;
     }
     return left;
    }
}


注意事项


while(right>=0&&nums[right]==val)  right--;

其中的right>=0不能改为right>0;否则只有一个元素时候会输出空值

JAVA移除数组元素方法 java数组移除指定元素_java_05




JAVA移除数组元素方法 java数组移除指定元素_数据结构_06


总结:

一定要搞清楚算法流程,其次要注意边界情况,一不小心就会报错。