数组实例 java

1 内存对齐

内存对齐是由于CPU读取内存时按照块来读取,块的大小可以为2,4,6,8个字节,具体读取多少个字节和硬件设计有关。因此按照块来读取就会出现所读取数据在一个或者几个块的情况,导致读取操作增加。
在这里插入图片描述
这种情况下,四个四个字节读取,刚好一次寻址找到。
在这里插入图片描述
第一次:0,1,2,3 第二次:4,5,6,7 第三次:合并 【因此需要更多的时间】

2 不同语言内存管理

c/c++:它的内存管理是通过申请和释放堆的形式完全自主管理的
java:它是使用JVM作内存管理,
python:由私有堆空间管理的,所有的对象和数据结构都在私有堆空间里,只有解释器才能操作。
在这里插入图片描述

3 为什么指针在不同操作系统中占用内存不同

在32位操作系统中,指针占4个字节,也就是32位,可存放的数据大小为2^32,也就是4G,因此指针可以寻址4G空间内存。那么针对64位操作系统来说,它的计算机内存都已经超过4位了,因此再使用4字节的指针没有办法寻址到所有的内存空间。

4 二分法运用

4.1 二分查找

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) >> 1);
            if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid - 1;
            else
                return mid;
        }
        return -1;

    }
}

4.2 搜索插入位置

class Solution {
    public int searchInsert(int[] nums, int target) {  //元素找不到就返回它应该插入的位置
        int left = 0;
        int right = nums.length - 1;
        int glMid = 0;

        while (left <= right ){
            int mid = left + ((right - left) >> 1);
            if (nums[mid] < target)
            left = mid + 1;
            else if (nums[mid] > target)
            right = mid -1 ;
            else 
            return mid;
            glMid = right;
        }
        return glMid + 1;
    }
}

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

class Solution {
    public int[] searchRange(int[] nums, int target) {

        return new int[]{getLeftBorder(nums, target), getRightBorder(nums, target)};
        
    }
        int getLeftBorder(int[] nums, int target){  //查找左边界
            int left = 0;
            int right = nums.length - 1;
            int leMid = -1;

            while (left <= right){
                int mid = left + ((right - left) >> 1);
                if (nums[mid] > target)
                    right = mid -1;
                else if (nums[mid] < target)
                    left = mid + 1;
                else{
                    right -= 1;                      //找到了一个相等的,就把right往左移动一个
                    leMid = mid;
                }
            }
            return leMid; 
        }

        int getRightBorder(int[] nums, int target){     //查找右边界
            int left = 0;
            int right = nums.length - 1;
            int riMid = -1;

            while (left <= right){
                int mid = left + ((right - left) >> 1);
                if (nums[mid] > target)
                    right = mid -1;
                else if (nums[mid] < target)
                    left = left + 1;
                else{
                    left += 1;                      找到了一个相等的,就把left往右移动一个
                    riMid = mid;
                }      
            }
            return riMid; 
        }
           
}

4.4 计算非负整数的算数平方根

class Solution {
    public int mySqrt(int x) {
        int xLeft = 0;
        int xRight = x;
        int temp = 0;

        while (xLeft <= xRight){
            int mid = xLeft + ((xRight - xLeft) >> 1);
            if ((long)mid*mid > x)                     //long非常关键,超出int时需要使用
                xRight = mid - 1;
            else{
                temp = mid;
                xLeft = mid + 1;
            } 
        }
        return temp;
    }
}

4.5 计算平方根

class Solution {
    public boolean isPerfectSquare(int num) {
        int numLeft = 0;
        int numRight = num;

        while (numLeft <= numRight){
            int mid = numLeft + ((numRight - numLeft)/2);
            if ((long)mid*mid > num)                       //long能够防止超时
                numRight = mid - 1;
            else if((long)mid*mid < num)
                numLeft = mid + 1;
            else
            return true;
        }
        return false;
    }
}

5 双指针在数组中的应用

5.1 删除元素并返回删除后的数组长度

class Solution {
    public int removeElement(int[] nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
            if (nums[fastIndex] != val){                                 //如果不相等,则慢指针一直跟随快指针
                nums[slowIndex] = nums[fastIndex];
                slowIndex ++;
            }
        }                                                              //相等的时候快指针往前就好了
        return slowIndex;
    } 
}

5.2 删除数组中重复元素

class Solution {
    public int removeDuplicates(int[] nums) {

        int lowIndex = 0;

        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
            if (nums[lowIndex] != nums[fastIndex]){
                lowIndex ++;
                nums[lowIndex] = nums[fastIndex];         //直接用fastIndex的值覆盖lowIndex处的值
            }
        }
        return lowIndex + 1;
    }
}

5.3 移动零到最后

class Solution {
    public void moveZeroes(int[] nums) {

        int lowIndex = 0;

        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++){
            if (nums[fastIndex] != 0){
                nums[lowIndex] = nums[fastIndex];
                lowIndex ++;
            }
        }
        for (int i = lowIndex ; i < nums.length; i ++)   //在后面补齐0
            nums[i] = 0;
    }
}

5.4 有序数组的平方

class Solution {
    public int[] sortedSquares(int[] nums) {

        int[] result = new int[nums.length];
        int k = nums.length - 1;
        int leftPoint = 0;
        int rightPoint = nums.length - 1;

        while (leftPoint <= rightPoint){

            int leftP = nums[leftPoint] * nums[leftPoint];
            int rightP = nums[rightPoint] * nums[rightPoint];

            if (leftP <= rightP){
                result[k] = rightP;
                rightPoint --;
            }
            else{
                result[k] = leftP;
                leftPoint ++;
            }
            k --;
        }
        return result;
    }
}

5.5 滑动窗口找字串

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        
        for (int right = 0; right < nums.length; right ++) {
            sum += nums[right];
            while (sum >= target) {
                result =  Math.min(result, right - left + 1);
                sum -= nums[left];
                left ++;
            }
        }
        return result == Integer.MAX_VALUE?0:result;              //如果字串长度超过了整数的最大长度,则返回0
    }
}

5.6 螺旋矩阵

class Solution {
    public int[][] generateMatrix(int n) {

        int loop = 0;               //圈的个数
        int mid = n / 2;                //中间那个数,如果是奇数要单独处理
        int[][] res = new int[n][n];  //创建新数组存数据
        int count = 1;                //填充的数字
        int i=0,j=0;                      //i,j分别代表行和列
        int start = 0;


        while (loop < n/2 ){
            loop ++;
            //第一排从左到右
            for (j = start; j < n - loop; j ++)      //n -loop是一个很好的反向思维
                res[start][j] = count ++;

            //最后一列从上到下
            for (i = start; i < n - loop; i ++)
                res[i][j] = count ++;

            //最后一行从右到左
            for (; j >= loop; j --)
                res[i][j] = count ++;
            
            //第一列从下到上
            for (; i >= loop; i --)
                res[i][j] = count ++;

            start ++;
        }
        if (n % 2 == 1)
        res[mid][mid] = count;
    return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值