首页 > 编程语言 >Leetcode刷题的一些记录(Java)

Leetcode刷题的一些记录(Java)

时间:2025-01-11 12:11:16浏览次数:1  
标签:Java nums int res ++ length 数组 Leetcode 刷题

Leetcode刷题

一、理论:

1. 数组:

https://programmercarl.com/数组理论基础.html

C++中二维数组在地址空间上是连续的

像Java是没有指针的,同时也不对程序员暴露其元素的地址,寻址操作完全交给虚拟机。

所以看不到每个元素的地址情况,这里我以Java为例,也做一个实验。

public static void test_arr() {
    int[][] arr = {{1, 2, 3}, {3, 4, 5}, {6, 7, 8}, {9,9,9}};
    System.out.println(arr[0]);
    System.out.println(arr[1]);
    System.out.println(arr[2]);
    System.out.println(arr[3]);
}

输出的地址为:

[I@7852e922
[I@4e25154f
[I@70dea4e
[I@5c647e05

这里的数值也是16进制,这不是真正的地址,而是经过处理过后的数值了,我们也可以看出,二维数组的每一行头结点的地址是没有规则的,更谈不上连续。所以Java的二维数组可能是如下排列的方式:

算法通关数组3

2. 哈希表

哈希表能解决什么问题呢,一般哈希表都是用来快速判断一个元素是否出现集合里。

哈希表1

但是要注意,使用数组来做哈希的题目,是因为题目都限制了数值的大小。

而这道题目没有限制数值的大小,就无法使用数组来做哈希表了。

而且如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。

  • 那有同学可能问了,遇到哈希问题我直接都用set不就得了,用什么数组啊。

直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。

二、常见技巧以及注意事项

1. 防止溢出

对数组元素之和进行取余,不要所有的加载一起之后再取余,边加边取余

以及:(2+4)/2=3 = 2+(4-2)/2=3

int mid = left + ((right - left) >> 1);// 防止溢出 等同于(left + right)/2

2. 双指针法

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

定义快慢指针

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新 新数组下标的位置

3. 滑动窗口

https://programmercarl.com/0209.长度最小的子数组.html#算法公开课

209.长度最小的子数组 leetcode_209

三、题目:

leetcode100

1. 两数之和

image-20250109210228094

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int res[]=new int[2];
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] + nums[j] == target) {
                    res[0]=i;
                    res[1]=j;
                    return res;
                }
            }
        }
        return res;//这里只要有返回就行 null也可以
    }
}

2. 两数相加

image-20250109210444197

image-20250109210452426

1、代码随想录:数组

704. 二分查找

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

27. 移除元素

image-20250109220455986

暴力解:

27.移除元素-暴力解法

class Solution {
    public int removeElement(int[] nums, int val) {
        int n=nums.length;
        for(int i = 0; i < n; i++){
            if(nums[i] == val){
                for(int j = i+1; j < n; j++){
                    nums[j-1] = nums[j];
                }
                i--;//注意这里的更新
                n--;
            }
        }
        return n;
    }
}

双指针:

27.移除元素-双指针法

class Solution {
    public int removeElement(int[] nums, int val) {
        // 快慢指针
        int slowIndex = 0;
        //基本思想:slowIndex  : 已经删除val元素的新数组的下标的位置
        //fastIndex : 寻找新数组的元素 ,新数组就是不含有目标元素的数组
        for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
            if (nums[fastIndex] != val) {//如果原数组中的元素不等于val,那么就是属于新数组的元素
                //复制到新数组中的对应的位置
                nums[slowIndex] = nums[fastIndex];
                slowIndex++;
            }
        }
        return slowIndex;
    }
}

977. 有序数组的平方

image-20250110142741780

暴力解

class Solution {
    public int[] sortedSquares(int[] nums) {
        for (int i = 0; i < nums.length; i++) {
            nums[i] = nums[i] * nums[i];
        }
        Arrays.sort(nums);
        return nums;
    }
}

双指针

class Solution {
    public int[] sortedSquares(int[] nums) {
        int n = nums.length;
        int[] res = new int[n];
        int left = 0, right = n - 1, index = n - 1;
        while (left <= right) {
            if (nums[left] * nums[left] > nums[right] * nums[right]) {
                res[index--] = nums[left] * nums[left];
                ++left;
            } else {
                res[index--] = nums[right] * nums[right];
                --right;
            }
        }
        return res;
    }
}

209. 长度最小的子数组

image-20250110163455186

暴力解

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int sum = 0;
        int res = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum=0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                if (sum >= target) {
                    res = (j - i + 1) < res ? (j - i + 1) : res;
                    break;
                }
            }
        }
        return res == Integer.MAX_VALUE ? 0 : res;//如果res没有被赋值,说明数组元素的综合没有超过target
    }
}

滑动窗口:

209.长度最小的子数组

leetcode_209
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int slow = 0,sum=0,res=Integer.MAX_VALUE;//slow 滑动窗口起始位置
        for(int fast = 0;fast<nums.length;fast++){
            sum+=nums[fast];
            while(sum>=target){// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
                res=Math.min(res,fast-slow+1);
                sum-=nums[slow++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置).可以发现滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。
            }
        }
        return res==Integer.MAX_VALUE?0:res;
    }
}

59. 螺旋矩阵 II

image-20250110180420532 img
class Solution {
    public int[][] generateMatrix(int n) {
        int[][] matrix = new int[n][n];
        int loop = 0, left = 0, right = n - 1, top = 0, bottom = n - 1, cnt = 1;
        while (loop <= n / 2) {
            for (int i = left; i <= right - 1; i++) {
                matrix[top][i] = cnt++;
            }
            for (int i = top; i <= bottom - 1; i++) {
                matrix[i][right] = cnt++;
            }
            for (int i = right; i >= left+1; i--) {
                matrix[bottom][i] = cnt++;
            }
            for (int i = bottom; i >= top+1; i--) {
                matrix[i][left] = cnt++;
            }
            loop++;
            left++;
            right--;
            bottom--;
            top++;
        }
        if(n%2!=0){
            matrix[n/2][n/2] = cnt;
        }
        return matrix;
    }
}

3. 代码随想录:哈希表

242. 有效的字母异位词

image-20250110182651980

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length())
            return false;
        int[] record = new int[26];
        for (int i = 0; i < s.length(); i++) {
            record[s.charAt(i) - 'a']++;
        }
        for (int i = 0; i < t.length(); i++) {
            record[t.charAt(i) - 'a']--;
        }
        for (int count : record) {
            if (count != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
                return false;
            }
        }
        return true;
    }
}

349. 两个数组的交集

image-20250110184748989
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        int []hash1 = new int[1001];
        int []hash2 = new int[1001];
        for (int i = 0; i < nums1.length; i++) {
            hash1[nums1[i]]++;
        }
        for (int i = 0; i < nums2.length; i++) {
            hash2[nums2[i]]++;
        }
        ArrayList<Integer> resTmp = new ArrayList<>();//ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
        for (int i = 0; i < hash1.length; i++) {
            if (hash1[i] >0 &&  hash2[i]>0) {//出现一次或者多次的,都记录其中了
                resTmp.add(i);
            }
        }
        int[] res = new int[resTmp.size()];//返回的是正常的数组,不是ArrayList类型
        for (int i = 0; i < res.length; i++) {
            res[i] = resTmp.get(i);
        }
        return res;
    }
}

标签:Java,nums,int,res,++,length,数组,Leetcode,刷题
From: https://www.cnblogs.com/xinyangblog/p/18665441

相关文章

  • 如何加密 PL/SQL 程序?思维导图 代码示例(java 架构)
    加密PL/SQL程序通常指的是保护存储在数据库中的PL/SQL代码,防止未经授权的用户查看或修改。Oracle数据库提供了一些方法来实现这一点,比如使用WRAP工具或者通过DBMS_DDL.CREATE_WRAPPED包来进行源代码的加密。思维导图结构-加密PL/SQL程序-使用WRAP工具......
  • 【精选】基于Java的新闻发布及管理系统设计与实现(源码+定制+开发)新闻发布管理系统、在
    博主介绍:  ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生......
  • 阿里开源项目Arthas,java开源诊断工具使用教程
    摘要:最近在项目中遇到一个问题,客户那边部署的项目线上出现了问题,需要远程调试,单凭log日志很难判断问题出现的原因,且无法进行远程debug调。,一开始是通过加日志的方式去排查问题,但日志加上之后还需要重新部署,这样来来回回部署了好几次,这方案非常浪费时间。了解到Arthas开源工具可以......
  • HTML、CSS与JavaScript基础入门指南
    HTML、CSS与JavaScript基础入门指南在当今的互联网时代,网页开发已成为一项基础且重要的技能。本文将带你快速了解HTML、CSS和JavaScript的基础知识,帮助你构建简单的网页并实现基本的交互效果。一、HTML:网页的骨架HTML(HyperTextMarkupLanguage)是构建网页的基础语言。它通过标......
  • day01-Java入门-cnblog
    day01——Java基础入门Hello,各位小伙伴大家好,欢迎来到Java的世界,咱们正式开干!!!一、Java背景知识在正式开干之前,我们先了解一下Java的背景知识,方便以后你在和大家聊Java的时候可以说到一块去。1.1Java语言的历史Java是哪家公司的产品?Java是美国Sun(StanfordUniversityNe......
  • JAVA并发编程系列 (二)
             目录1.javastart如何调用到run方法?2.synchronized关键字的底层原理,synchronize锁是如何实现的?3.notify和notifyAll区别4.synchronize锁优化锁膨胀过程?5.AQS原理6.ReentrantLock和synchronized区别7.Lock高级功能?8.简述下CAS?9.int......
  • 咱们继续学Java——高级篇 第六十三篇:之XSLT转换示例程序全解析
    咱们继续学Java——高级篇第六十三篇:之XSLT转换示例程序全解析在Java编程的学习道路上,我们始终携手共进,不断深入探索知识的领域。此前我们学习了XSL转换(XSLT)的高级应用及在Java中的实现原理,今天我们将全面解析文档中的示例程序TransformTest,深入理解如何在Java中应用XSLT......
  • 02 Java基础
    注释定义:写代码时,随着项目变复杂要用到注释,注释是给写代码的人看的,且写注释是好习惯。类型:单行注释 //多行注释/*注释*/文档注释/**注释*/标识符关键字:Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符标识符注意点:标识符要......
  • Java基础:Iterator迭代器
    一、什么是Iterator:迭代器(Iterator)是一个对象,它的工作是遍历并目标序列中的对象,它提供了一种访问一个容器(container)对象中的各个元素的方法,把访问逻辑从不同类型的集合类中抽象出来,又不必暴露该对象内部细节。通过迭代器,开发人员不需要了解容器底层的结构,就可以实现对容器......
  • Java异常处理
    1.异常:异常是错误,运行时出错(编译时可以通过),编译时异常就是敲代码的时候错误2.抛异常:创建一个错误对象,把错误对象丢出来3.捕获异常:默认由JVM来把错误信息进行捕获,在错误处停止运行,后面的正确代码不会再运行4.异常的分类:runtimeexception运行时异常其他exceptionerrorexcept......