《代码随想录》刷题笔记——数组篇【java实现】

news2024/11/26 16:57:25

*二分查找

题目链接

https://leetcode.cn/problems/binary-search/

左闭右闭区间实现

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)
/**
 * 左闭右闭写法
 *
 * @param nums
 * @param target
 * @return
 */
public static int search1(int[] nums, int target) {
    if (nums == null || nums.length == 0) {
        return -1;
    }
    int left = 0;
    int right = nums.length - 1;
    // 要是没有等号的话,在{5}里面找5就会出问题了
    while (left <= right) {
        int center = (left + right) / 2;
        if (target == nums[center]) {
            return center;
        } else if (target > nums[center]) {
            left = center + 1;
        } else {
            right = center - 1;
        }
    }
    return -1;
}

左闭右开区间实现

  • 时间复杂度:O(log n)
  • 空间复杂度:O(1)
/**
 * 左闭右开写法
 *
 * @param nums
 * @param target
 * @return
 */
public static int search2(int[] nums, int target) {
    if (nums == null || nums.length == 0) {
        return -1;
    }
    int left = 0;
    // 区别点
    int right = nums.length;
    // 区别点
    while (left < right) {
        int center = (left + right) / 2;
        if (target == nums[center]) {
            return center;
        } else if (target > nums[center]) {
            left = center + 1;
        } else {
            // 区别点
            // 虽然已经知道center位置的元素不是要找的元素,但是因为是左闭右开,因此right还是指向center
            // 后面无论怎么循环,都不会再使用到center这个为止,因为center = (left + right) / 2永远小于right
            right = center;
        }
    }
    return -1;
}

*移除元素

题目链接

https://leetcode.cn/problems/remove-element/

暴力求解

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)
public static int removeElement(int[] nums, int val) {
    int sameNum = 0;
    int i = 0;
    while (i < nums.length - sameNum) {
        if (val == nums[i]) {
            // 将后面的元素前移过来
            for (int j = i; j < nums.length - 1 - sameNum; j++) {
                nums[j] = nums[j + 1];
            }
            sameNum++;
        }
        if (val == nums[i]) {
            // 前移过来的数值和val一样,将i--
            i--;
        }
        i++;
    }
    return nums.length - sameNum;
}

双指针

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

【思想】

通过一个快指针和慢指针在一个for循环下完成两个for循环的工作,将快指针的值赋给慢指针

slow:新数组存储值的索引,因为每次存储完新数组的值,都会将slow++,因此最后直接返回slow即可,需要返回slow+1

fast:用来去前面探索那些不是val的值,然后将这个值赋给slow对应的位置

在这里插入图片描述

/**
 * 双指针
 *
 * @param nums
 * @param val
 * @return
 */
public static int removeElement1(int[] nums, int val) {
    int slow = 0;
    for (int fast = 0; fast < nums.length; fast++) {
        if (nums[fast] != val) {
            // 如果快指针找的数值不是val,就需要将其存储到新数组中
            // 同时slow++,以便存储下一个新数组的值
            nums[slow++] = nums[fast];
        }
    }
    return slow;
}

相向双指针法

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)

上面的实现方法并没有改变元素的相对位置,相向双指针方法改变了元素相对位置,但是确保移动最少元素

在这里插入图片描述

/**
 * 想向双指针
 *
 * @param nums
 * @param val
 * @return
 */
public static int removeElement(int[] nums, int val) {
    int slow = 0, fast = nums.length - 1;
    while (slow <= fast) {
        // slow赋值为第一个等于val的索引
        while (slow <= fast) {
            if (nums[slow] != val) {
                slow++;
            } else {
                break;
            }
        }
        // fast赋值为最后一个等于val的索引
        while (fast >= slow) {
            if (nums[fast] == val) {
                fast--;
            } else {
                break;
            }
        }
        if (slow < fast) {
            nums[slow++] = nums[fast--];
        }
    }
    // slow最后一定指向的是 新数组末尾元素的下一个元素
    return slow;
}

*有序数组的平方

题目链接

https://leetcode.cn/problems/squares-of-a-sorted-array/

暴力求解

  1. 先对数组的每个元素求平方
  2. 对数组升序排序

时间复杂度:O(n)+排序算法的时间复杂度

双指针

【思路】

数组本身就是非递减顺序的,只不过负数在平方之后可能会变大,因此只需要用两端来比较就能知道那个数字的平方更大

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

在这里插入图片描述

public static int[] sortedSquares(int[] nums) {
    int left = 0, right = nums.length - 1;
    // 用于存储排序之后的结果
    int[] result = new int[nums.length];
    for (int i = nums.length - 1; i >= 0; i--) {
        int leftValue = nums[left];
        int rightValue = nums[right];
        if (leftValue * leftValue >= rightValue * rightValue) {
            result[i] = leftValue * leftValue;
            left++;
        } else {
            result[i] = rightValue * rightValue;
            right--;
        }
        System.out.println(Arrays.toString(result));
    }
    return result;
}

*长度最小的子数组

题目链接

https://leetcode.cn/problems/minimum-size-subarray-sum/

暴力求解

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

注意,子数组是原数组中连续的几个元素的集合

public int minSubArrayLen(int target, int[] nums) {
    // 最小子数组长度
    int minLen = nums.length + 1;
    for (int i = 0; i < nums.length; i++) {
        int sum = 0;
        for (int j = i; j < nums.length; j++) {
            sum += nums[j];
            if (sum >= target) {
                // 已经>=target,可以暂停了
                if ((j - i + 1) < minLen) {
                    minLen = j - i + 1;
                    break;
                }
            }
        }
    }
    return minLen == nums.length + 1 ? 0 : minLen;
}

部分案例已经超出时间限制

在这里插入图片描述

滑动窗口

  • 时间复杂度:O(n):不能以为for里放一个while就是O(n^2), 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)
  • 空间复杂度:O(1)

在这里插入图片描述

/**
 * 滑动窗口
 *
 * @param target
 * @param nums
 * @return
 */
public int minSubArrayLen1(int target, int[] nums) {
    // 最小子数组长度
    int minLen = nums.length + 1;
    int i = 0;
    int sum = 0;
    for (int j = 0; j < nums.length; j++) {
        // j++,窗口终止位置后移一位,sum添加相应的元素
        sum += nums[j];
        while (sum >= target) {
            // 窗口内的元素总和已经超过target,尝试将窗口的起始位置后移,即i++
            if ((j - i + 1) < minLen) {
                minLen = j - i + 1;
            }
            // sum移除窗口起始位置的元素值
            sum -= nums[i++];
        }
    }
    return minLen == nums.length + 1 ? 0 : minLen;
}

螺旋矩阵

【思想】

这道题主要是考代码能力,注意每次循环都是左开右闭就行

【我写的程序】

public static int[][] generateMatrix1(int n) {
    int[][] result = new int[n][n];
    int curNum = 1;
    int target = n * n;
    int initN = n;
    // 圈数
    int cirCleNum = 0;
    while (curNum <= target) {
        if (curNum == target) {
            result[cirCleNum][cirCleNum] = curNum;
            System.out.println("---------------------填中心---------------------");
            for (int i = 0; i < result.length; i++) {
                System.out.println(Arrays.toString(result[i]));
            }
            break;
        }
        // 填上边
        for (int i = 0; i < n - 1; i++) {
            result[cirCleNum][i + cirCleNum] = curNum++;
        }
        System.out.println("---------------------填上边---------------------");
        for (int i = 0; i < result.length; i++) {
            System.out.println(Arrays.toString(result[i]));
        }
        // 填右边
        for (int i = 0; i < n - 1; i++) {
            result[i + cirCleNum][initN - 1 - cirCleNum] = curNum++;
        }
        System.out.println("---------------------填右边---------------------");
        for (int i = 0; i < result.length; i++) {
            System.out.println(Arrays.toString(result[i]));
        }
        // 填下边
        for (int i = n - 1; i > 0; i--) {
            result[initN - 1 - cirCleNum][i + cirCleNum] = curNum++;
        }
        System.out.println("---------------------填下边---------------------");
        for (int i = 0; i < result.length; i++) {
            System.out.println(Arrays.toString(result[i]));
        }
        // 填左边
        for (int i = n - 1; i > 0; i--) {
            result[i + cirCleNum][cirCleNum] = curNum++;
        }
        System.out.println("---------------------填左边---------------------");
        for (int i = 0; i < result.length; i++) {
            System.out.println(Arrays.toString(result[i]));
        }
        System.out.println("======================================================================");
        cirCleNum += 1;
        n -= 2;

    }

    return result;
}

【别人的代码】

public int[][] generateMatrix(int n) {
    int loop = 0;  // 控制循环次数
    int[][] res = new int[n][n];
    int start = 0;  // 每次循环的开始点(start, start)
    int count = 1;  // 定义填充数字
    int i, j;

    while (loop++ < n / 2) { // 判断边界后,loop从1开始
        // 模拟上侧从左到右
        for (j = start; j < n - loop; j++) {
            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[start][start] = count;
    }

    return res;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/978543.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于工信部发布的app备案以及小程序备案流程

一、相关政策 通知&#xff1a;https://beian.miit.gov.cn/#/Integrated/lawStatute 腾讯备案&#xff1a;网站备案 首次备案-网站备案-文档中心-腾讯云 阿里备案&#xff1a;网站备案_ICP备案_备案迁移_备案-阿里云 二、遇到的问题 APP备案 安卓获取平台公钥方法&#xf…

Vue + Element UI 前端篇(九):接口格式定义

接口请求格式定义 前台显示需要后台数据&#xff0c;我们这里先把前后端交互接口定义好&#xff0c;没有后台的时候&#xff0c;也方便用mock模拟。 接口定义遵循几个规范&#xff1a; 1. 接口按功能模块划分。 系统登录&#xff1a;登录相关接口 用户管理&#xff1a;用户…

Redis-1.4-过期策略

1 设置带过期时间的 key # 时间复杂度&#xff1a;O&#xff08;1&#xff09;&#xff0c;最常用方式 expire key seconds# 字符串独有方式 setex(String key, int seconds, String value)除了string独有设置过期时间的方法&#xff0c;其他类型都需依靠expire方法设置时间&a…

说说MySQL回表查询与覆盖索引

分析&回答 什么是回表查询&#xff1f; 通俗的讲就是&#xff0c;如果索引的列在 select 所需获得的列中&#xff08;因为在 mysql 中索引是根据索引列的值进行排序的&#xff0c;所以索引节点中存在该列中的部分值&#xff09;或者根据一次索引查询就能获得记录就不需要…

【Linux】Qt Remote之Remote开发环境搭建填坑小记

总体思路 基于WSL2&#xff08;Ubuntu 22.04 LTS&#xff09;原子Alpha开发板进行Qt开发实验&#xff0c;基于Win11通过vscode remote到WSL2&#xff0c;再基于WSL2通过Qt 交叉编译&#xff0c;并通过sshrsync远程到开发板&#xff0c;构建起开发工具链。 Step1 基于Win11通过…

Mock接口测试

什么是mock? 测试桩&#xff0c;模拟被测对象的返回&#xff0c;用于测试 通常意义的mock指的就是mock server, 模拟服务端返回的接口数据&#xff0c;用于前端开发&#xff0c;第三方接口联调 为什么要mock? 1. 解决依赖问题&#xff1a;当我们测试一个接口或者功能模块…

Python Opencv实践 - 轮廓特征(最小外接圆,椭圆拟合)

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/stars.PNG") plt.imshow(img[:,:,::-1])#轮廓检测 img_gray cv.cvtColor(img, cv.COLOR_BGR2GRAY) ret,thresh cv.threshold(img_gray, 127, 255, 0) contou…

Unity汉化一个插件 制作插件汉化工具

我是编程一个菜鸟&#xff0c;英语又不好&#xff0c;有的插件非常牛&#xff01;我想学一学&#xff0c;页面全是英文&#xff0c;完全不知所措&#xff0c;我该怎么办啊...尝试在Unity中汉化一个插件 效果&#xff1a; 思路&#xff1a; 如何在Unity中把一个自己喜欢的插件…

Flutter 最优秀动画库「完全商业化」,Rive 2 你全面了解过吗?

说到 rive &#xff0c;非 Flutter 开发者可能会感觉比较陌生&#xff0c;而做过 Flutter 开发的可能对 rive 会有所耳闻&#xff0c;因为 rive 在一开始叫 flare &#xff0c;是 2dimensions 公司的开源动画产品&#xff0c;在发布之初由于和 Flutter 团队有深入合作&#xff…

golang获取prometheus数据(prometheus/client_golang包)

文章目录 1. 创建链接1.1 语法1.2 完整示例 2. 简单查询2.1 语法2.2 完整示例 3. 范围值查询3.1 语法3.2 完整示例 【附官方示例】 1. 创建链接 1.1 语法 语法 func NewClient(cfg Config) (Client, error)结构体 type Config struct {Address stringClient *ht…

16-数据结构-图的存储结构

简介&#xff1a;主要为图的顺序存储和链式存储。其中顺序存储即邻接矩阵的画法以及代码&#xff0c;邻接矩阵又分为有权图和无权图&#xff0c;区别就是有数据的地方填权值&#xff0c;无数据的地方可以填0或者∞&#xff0c;而有权图和无权图&#xff0c;又细分为有向图和无向…

阿里云服务器退款政策及退款流程解析

阿里云服务器如何退款&#xff1f;云服务器在哪申请退款&#xff1f;在用户中心订单管理中的退订管理中退款&#xff0c;阿里云百科分享阿里云服务器退款流程&#xff0c;包括申请退款入口、云服务器退款限制条件、退款多久到账等详细说明&#xff1a; 目录 阿里云服务器退款…

FPGA GTH 全网最细讲解,aurora 8b/10b协议,HDMI板对板视频传输,提供2套工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、GTH 全网最细解读GTH 基本结构GTH 发送和接收处理流程GTH 的参考时钟GTH 发送接口GTH 接收接口GTH IP核调用和使用 4、设计思路框架视频源选择silicon9011解码芯片配置及采集动态彩条视频数据组包GTH aurora 8b/10…

【Java 基础篇】深入理解 Java 内部类:嵌套在嵌套中的编程奇妙世界

在 Java 编程中&#xff0c;内部类&#xff08;Inner Class&#xff09;是一个非常强大且灵活的概念&#xff0c;它允许在一个类的内部定义另一个类。内部类可以访问外部类的成员&#xff0c;包括私有成员&#xff0c;这使得内部类在许多编程场景中都非常有用。本篇博客将详细介…

js如何实现数组去重的常用方法

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用 Set&#xff08;ES6&#xff09;⭐ 使用 filter 和 indexOf⭐ 使用 reduce⭐ 使用对象属性⭐ 使用 includes 方法&#xff08;ES6&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方…

$ref属性的介绍与使用

在Vue.js中&#xff0c;$ref是一个特殊的属性&#xff0c;用于访问Vue组件中的DOM元素或子组件实例。它允许你直接访问组件内部的DOM元素或子组件&#xff0c;并且可以在需要时进行操作或修改。以下是有关$ref的详细介绍和示例演示&#xff0c;给大家做一个简单的介绍和概念区分…

库中是如何实现string类的?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f…

如何查看B站UP主数据?如何看懂B站数据?

bilibili是独特且稀缺的PUGC视频社区&#xff0c;拥有浓厚社区氛围的视频社区。有别于短视频&#xff0c;PUGC视频创作门槛高&#xff0c;视频内容更充实&#xff0c;bilibili是PUGC视频行业的领跑者&#xff0c;同时&#xff0c;bilibili拥有社区产品特有的高创作渗透率和高互…

SQL SERVER 如何实现UNDO REDO 和PostgreSQL 有近亲关系吗

开头还是介绍一下群&#xff0c;如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,SQL Server&#xff0c;Redis &#xff0c;Oracle ,Oceanbase 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请加微信号 l…

分类任务评价指标

分类任务评价指标 分类任务中&#xff0c;有以下几个常用指标&#xff1a; 混淆矩阵准确率&#xff08;Accuracy&#xff09;精确率&#xff08;查准率&#xff0c;Precision&#xff09;召回率&#xff08;查全率&#xff0c;Recall&#xff09;F-scorePR曲线ROC曲线 1. 混…