day02_数组第二部分

977. 有序数组平方

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        # sqare
        for i in range(0,len(nums)):
            nums[i] = nums[i] * nums[i]

        # 
        for i in range(0, len(nums)-1):
            for j in range(i+1, len(nums)):
                if nums[i] > nums[j]:
                    t = nums[j]
                    nums[j] = nums[i]
                    nums[i] = t
        
        return nums

直接暴力解题,排序算法 o ( n 2 ) o(n^2) o(n2),超出时间限制。

双指针法

两头遍历,从最大赋值

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        lens = len(nums)
        result = [0]*lens
        left, right = 0, lens - 1
        k = right
        while left <= right:
            if nums[left] * nums[left] > nums[right] * nums[right]:
                result[k] = nums[left] * nums[left]
                left += 1
            else:
                result[k] = nums[right] * nums[right]
                right -= 1
            k -= 1
        return result

209 长度最小的子数组

暴力解题:超时

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int minl = nums.length + 1;
        for(int i = 0; i < nums.length; i++){
            int sum = nums[i];
            if(i == nums.length - 1 && nums[i] < target){
                break;
            }else if(nums[i] >= target){
                return 1;
            }
            for(int j = i + 1; j < nums.length; j++){
                sum += nums[j];
                if(sum >= target && (j-i+1) < minl){
                    minl =  j-i+1;
                }
            }
        }
        if(minl == nums.length + 1){
            return 0;
        }
        return minl;
    }
}

提交版本2:改成滑动窗口法,还超时?错误。

这里并不是正确的滑动窗口,滑动窗口中的前后指针都只往前走。还是枚举。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int fast = 0;
        int slow = 0;
        int result = nums.length+1; 
        for(slow = 0; slow < nums.length; slow++){
            int sum = nums[slow];
            fast = slow;
            boolean ok = false;
            while(sum < target){
                if(fast >= nums.length - 1){
                    break;
                }
                fast++;
                sum += nums[fast];
            }
            if(sum >= target && (fast - slow+1)< result){
                result = fast-slow+1;
            }
        }
        if(result == nums.length + 1){
            return 0;
        }
        return result;
    }
}

滑动窗口

一个for循环里做两个for循环里的事情;一个起始位置,一个终止位置;

如果for循环里是起始位置,则与暴力法相同;for循环里应是终止位置,动态调整里面的起始位置,控制集合的和。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int start = 0;
        int end = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for(end = 0; end < nums.length; end++){
            sum += nums[end];

            while(sum >= target){ 
                int subL = end - start +1;
                result = Math.min(subL, result);
                sum -= nums[start];
                start ++;
            }
            
        }
        if(result == Integer.MAX_VALUE){
            return 0;
        }
        return result;
    }
}

59 螺旋矩阵2

给你一个正整数 n ,生成一个包含 1n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix

提交版本1: 写四个方向的移动,通过,但调试较久,且代码冗余。

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] directs = {{0,1},{1,0},{0,-1},{-1,0}};
        int direct = 0;
        int[][] result = new int[n][n];
        int all = n*n;
        int i = 0;
        int j = 0;
        for(int id = 1; id<=all; id++){
            if(result[i][j] ==0){
                result[i][j] = id;
            }else{
                // 当前方向下的新坐标
                int new_i = i+directs[direct][0];
                int new_j = j+directs[direct][1];
                if(new_i>=n || new_j>=n || new_i<0 || new_j<0){
                    direct = (++direct)%4;
                    new_i = i+directs[direct][0];
                    new_j = j+directs[direct][1];
                }
                if(result[new_i][new_j] == 0){
                    result[new_i][new_j] = id;
                }else{
                    direct = (++direct)%4;
                    new_i = i+directs[direct][0];
                    new_j = j+directs[direct][1];
                    if(result[new_i][new_j] == 0){
                        result[new_i][new_j] = id;
                    }else{
                        break;
                    }
                }
                i = new_i;
                j = new_j; 
            }
        }
        return result;
    }
}

提交版本2: 模拟矩阵后,按照数量填充,左闭右开。

class Solution {
    public int[][] generateMatrix(int n) {
        int loop = n-1;
        int count = 1;
        int startx = 0;
        int starty = 0;
        int[][] result = new int[n][n];
        int offset = 0;
        while(loop > 0){
            int i = startx;
            int j = starty;
            for(j= starty; j<n-offset-1;j++){
                result[startx][j] = count++;
            }
            //横条
            for(i = startx; i<n-offset-1; i++){
                result[i][j] = count++;
            }
            //竖条
            for(;j>starty;j--){
                result[i][j] = count++;
            }
            //下条
            for(;i>startx;i--){
                result[i][j] = count++;
            }
            //左条
            offset ++;
            startx ++;
            starty ++;
            loop -= 2;
        }
        if(loop == 0){
            result[startx][starty] = count++;
        }
        return result;
    }
}

数组总结

Java的二维数组在内存中不是 3*4 的连续地址空间,而是四条连续的地址空间组成!

二分法

  • 二分法时间复杂度:O(logn)

双指针法

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

滑动窗口

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。

模拟行为

循环不变量原则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值