LeetCode 热题 HOT 100(P21~P30)

news2024/11/14 21:15:55

 系列文章: 

LeetCode 热题 HOT 100(P1~P10)-CSDN博客

LeetCode 热题 HOT 100(P11~P20)-CSDN博客

LeetCode 热题 HOT 100(P21~P30)-CSDN博客

LC48rotate_image

. - 力扣(LeetCode)

题目:

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

解法:

也是套路题,乍一看完全没思路,旋转到底要怎么弄?实际的解法是把旋转变成翻转的组合,比如这里顺时针旋转90度,相当于先上下翻转,再沿对角线翻转,针对翻转的代码就比较好写了。
 public void rotate(int[][] matrix) {
        final int row = matrix.length;
        final int col = matrix[0].length;
        //上下翻转
        for (int i = 0; i < row / 2; i++) {
            for (int j = 0; j < col; j++) {
                swap(matrix, i, j, row - i - 1, j);
            }
        }
        //对角线翻转
        for (int i = 0; i < row; i++) {
            for (int j = i + 1; j < col; j++) {
                swap(matrix, i, j, j, i);
            }
        }
    }

    private void swap(int[][] matrix, int rowIndex, int colIndex, int newRowIndex, int newColIndex) {
        int tmp = matrix[rowIndex][colIndex];
        matrix[rowIndex][colIndex] = matrix[newRowIndex][newColIndex];
        matrix[newRowIndex][newColIndex] = tmp;
    }

LC49group_anagrams

. - 力扣(LeetCode)

题目:

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 1:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]

输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

解法:

理解题目的意思有点费劲,实际就是由相同字母组成单词的集合,很自然的想到用HashMap 。

 public List<List<String>> groupAnagrams(String[] strs) {
        Map<String, List<String>> cache = new HashMap<>();
        for (String str : strs) {
            final char[] chars = str.toCharArray();
            Arrays.sort(chars);
            cache.computeIfAbsent(new String(chars), (k) -> new ArrayList<String>()).add(str);
        }
        return new ArrayList<>(cache.values());
    }

写出代码不难,关键是能否写的尽量简练。

LC53maximum_subarray

. - 力扣(LeetCode)

题目:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组是数组中的一个连续部分。

输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。

解法:

一般这种最*** 的题目理论上都可以用动态规划,核心难点是动态数组的定义,很多时候动态数组定义好了,动态推导方程也能比较简单的推演出来。

动态数组:dp[i] 表示包含下标i的连续子数组最大和

动态方程:dp[i] = Max(i,dp[i-1]+i) 

比较好理解的,这里稍微解释下包含i的数组最大和,基本要看前一位最大和是否小于0,如果是负数带上前面的肯定更小,还不如自己玩(i),如果前面大于0,那么带上肯定更大。

public int maxSubArray(int[] nums) {
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        int max = dp[0];
        for (int i = 1; i < nums.length; i++) {
            dp[i] = Math.max(nums[i], dp[i - 1] + nums[i]);
            max = Math.max(max, dp[i]);
        }
        return max;
    }

因为i只跟i-1 有关,因此动态数组可以简化为单个变量,其实动态规划很多代码都可以简化为单个或多个变量,但是这样的话代码就不太好理解。

LC55jump_game

. - 力扣(LeetCode)

题目:

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

解法:

可能也算套路题,有思路之后很简单。其实就是每跳一步就记录当前能跳到的最远位置,然后一个个位置跳过去,判断当前记录最远位置能否到下一个。实际上也是动态规划的思路。

动态数组:dp[i] 表示在i位置时能跳到的最远下标

动态方程:dp[i] = max(dp[i-1],i+nums[i])

 public boolean canJump(int[] nums) {
        //表示能达到的最远距离
        int k = 0;
        for (int i = 0; i < nums.length; i++) {
            if (k < i) {
                return false;
            }
            k = Math.max(k, i + nums[i]);
        }
        //能抵达最后一块石头就ok
        return true;
    }

这里将动态数组精简为单个变量。

LC56merge_intervals

. - 力扣(LeetCode)

题目:

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

解法:

区间合并的问题,首先是排序,按照starti 排序。然后就是进行入队操作,在入队的时候跟队首元素进行比较,看下当前元素starti 是否大于队首元素的endi,如果大于说明需要开一个新的区间,如果小于那就加入当前区间。

public int[][] merge(int[][] intervals) {
        // 先按照区间起始位置排序
        Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);
        // 遍历区间
        List<int[]> result = new ArrayList<>();
        for (int[] interval : intervals) {
            // 如果结果数组是空的,或者当前区间的起始位置 > 结果数组中最后区间的终止位置,
            // 则不合并,直接将当前区间加入结果数组。
            if (result.isEmpty() || interval[0] > result.get(result.size() - 1)[1]) {
                result.add(interval);
            } else {
                final int[] ints = result.get(result.size() - 1);
                ints[1] = Math.max(ints[1], interval[1]);
            }
        }
        return result.toArray(new int[0][]);
    }

注意合并的写法,需要取当前元素的endi 和队首元素的endi 的最大值,在这里踩过坑。

LC62unique_paths

. - 力扣(LeetCode)

题目:

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?

解法:

因为每次只能向下或者向右移动一步,因此要走到右下角,上一步只能从下面下来,或者从左边过来。对每个位置来说也可以这么推断,这里动态数组定义比较直观dp[i,j] 就是走到坐标[i,j] 一共有多少路径。动态方程dp[i,j] = dp[i-1,j] + dp[i,j-1]  。这里还涉及到动态数组的初始化,第一列和第一排的走法只有1种。

 public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        //初始化行列的情况
        for (int i = 0; i < m; i++) {
            dp[i][0] = 1;
        }
        for (int i = 0; i < n; i++) {
            dp[0][i] = 1;
        }

        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m - 1][n - 1];
    }

LC64minimum_path

. - 力扣(LeetCode)

题目:

给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

解法:

这道题跟上一道类似,不同的是这里求最小和,其实走法是一样的,因为只能从上面或者左边过来。动态数组定义为当前位置的最小值,动态方程有所调整,dp[i,j]=min(dp[i-1,j],dp[j,i-1]) +nums[i,j] 。 

 public int minPathSum(int[][] grid) {
        final int m = grid.length, n = grid[0].length;
        int[][] dp = new int[m][n];
        dp[0][0] = grid[0][0];
        for (int i = 1; i < m; i++) {
            dp[i][0] = grid[i][0] + dp[i - 1][0];
        }
        for (int i = 1; i < n; i++) {
            dp[0][i] = grid[0][i] + dp[0][i - 1];
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[m - 1][n - 1];
    }

这里有个优化,可以不用新增动态数组dp ,直接在原数组grid 上直接操作,这样能节省内存开销。

LC70climbing_stairs

. - 力扣(LeetCode)

题目:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

解法:

经典的爬楼梯算法题,他可以用递归的方式,也可以使用动态规划的思路。这类题目乍一看没思路,实际跟上面机器人走路是一样,要么从前1个台阶过来,要么从前2个台阶过来。动态方程比较简单:dp[i] = dp[i-1]+dp[i-2] 。因为只涉及前2个值,可以用2个变量替代数组。

public int climbStairs(int n) {
        if (n < 3) {
            return n;
        }
        int one = 1;
        int two = 2;
        for (int i = 3; i <= n; i++) {
            int cur = one + two;
            one = two;
            two = cur;
        }
        return two;
    }

LC72edit_distance

. - 力扣(LeetCode)

题目:

给你两个单词 word1 和 word2, 请返回将 word1 转换成 word2 所使用的最少操作数  。

你可以对一个单词进行如下三种操作:

  • 插入一个字符
  • 删除一个字符
  • 替换一个字符

解法:

差不多也是套路题,这道题目跟机器走路的思路类似,可以参考下面的图

dp[i][j] 表示wrod1 的前 i 个字符转换成word2 的前j个字段所用的最小操作数 。相当于求最后一个格子的值。有点复杂的地方在于第一行和第一列作为空串进行初始化,第一行的意思是空串 ‘’ 变成'ros'  所需的最小步骤。第一列同理,这样就初始化好了动态数组。这里的动态方程有点复杂,需要分情况判断:

  • 当 word1[i] == word2[j],dp[i][j] = dp[i-1][j-1];
  • 当 word1[i] != word2[j],dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 ;
    • dp[i-1][j-1] 表示替换操作
    • dp[i-1][j] 表示删除操作
    • dp[i][j-1] 表示插入操作。
public int minDistance(String word1, String word2) {
        final int row = word1.length();
        final int col = word2.length();
        // 因为有初始行和初始列,所以这里长度+1
        int[][] dp = new int[row + 1][col + 1];
        for (int i = 0; i <= row; i++) {
            dp[i][0] = i;
        }
        for (int i = 0; i <= col; i++) {
            dp[0][i] = i;
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (word1.charAt(i) == word2.charAt(j)) {
                    dp[i + 1][j + 1] = dp[i][j];
                } else {
                    dp[i + 1][j + 1] = Math.min(Math.min(dp[i][j], dp[i][j + 1]), dp[i + 1][j]) + 1;
                }

            }
        }
        return dp[row][col];
    }

LC75sort_colors

. - 力扣(LeetCode)

题目:

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

解法:

套路题,需要了解思路。维护0,1,2的初始下标,其中0,1初始在0,2初始在len-1,然后迭代数组,对数组中的数字进行判断,并相应的移动下标。可以参考官方的讲解配图,比较好理解。

public void sortColors(int[] nums) {
        if (nums.length == 0) {
            return;
        }
        //定义几个下标,需要实现
        // all in [0, zero] = 0
        // all in (zero, i) = 1
        // all in (two, len - 1] = 2
        int zero = 0, cur = 0, two = nums.length - 1;
        while (cur <= two) {
            if (nums[cur] == 0) {
                swap(nums, zero, cur);
                zero++;
                cur++;
            } else if (nums[cur] == 1) {
                cur++;
            } else {
                swap(nums, cur, two);
                //注意 这个时候cur 不能移动,因为交换之后还要再判断下
                two--;
            }
        }
    }


private void swap(int[] nums, int i, int j) {
        final int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }

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

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

相关文章

【电路笔记】-场效应管(FET)电流源

场效应管(FET)电流源 文章目录 场效应管(FET)电流源1、概述2、偏置结 FET2.1 N沟道JFET偏置2.2 N沟道JFET输出特性3、JFET 作为恒流源4、JFET 零电压偏置5、JFET 负电压偏置6、FET 恒流源示例17、JFET电流源8、FET 恒流源示例29、FET 恒流源示例310、总结FET 恒流源使用 JFET 和…

SpringBoot3集成PostgreSQL

标签&#xff1a;PostgreSQL.Druid.Mybatis.Plus&#xff1b; 一、简介 PostgreSQL是一个功能强大的开源数据库系统&#xff0c;具有可靠性、稳定性、数据一致性等特点&#xff0c;且可以运行在所有主流操作系统上&#xff0c;包括Linux、Unix、Windows等。 通过官方文档可以…

学习刷题-13

3.23 hw机试【二叉树】 剑指offer32 剑指 offer32&#xff08;一、二、三&#xff09;_剑指offer 32-CSDN博客 从上到下打印二叉树I 一棵圣诞树记作根节点为 root 的二叉树&#xff0c;节点值为该位置装饰彩灯的颜色编号。请按照从 左 到 右 的顺序返回每一层彩灯编号。 输…

WiFi已连接却不可上网是什么原因?

很多使用wifi上网的用户都遇到过这样的问题,就是电脑已经连接了wifi,但就是上不了网。着到底是怎么回事呢?今天,极客狗带大家一起来找找WiFi已连接却不可上网是什么原因,并给出对应的解决方。 原因分析: 可能是ip地址冲突所导致,也有可能是宽带出先故障,不妨试试下面的…

OpenHarmony使用智能指针管理动态分配内存对象

概述 智能指针是行为类似指针的类&#xff0c;在模拟指针功能的同时提供增强特性&#xff0c;如针对具有动态分配内存对象的自动内存管理等。 自动内存管理主要是指对超出生命周期的对象正确并自动地释放其内存空间&#xff0c;以避免出现内存泄漏等相关内存问题。智能指针对…

装修行业万能DIY小程序源码系统 带完整的安装的代码包以及搭建教程

在如今数字化、智能化的时代背景下&#xff0c;装修行业也迎来了前所未有的发展机遇。为了满足广大装修从业者及业主的需求&#xff0c;罗峰给大分享了这款装修行业万能DIY小程序源码系统。该系统不仅提供了完整的安装代码包&#xff0c;还附带了详细的搭建教程&#xff0c;让用…

零基础入门数据挖掘系列之「特征工程」

摘要&#xff1a;对于数据挖掘项目&#xff0c;本文将学习应该从哪些角度做特征工程&#xff1f;从哪些角度做数据清洗&#xff0c;如何对特征进行增删&#xff0c;如何使用PCA降维技术等。 特征工程&#xff08;Feature Engineering&#xff09;对特征进行进一步分析&#xf…

详解机器学习概念、算法

目录 前言 一、常见的机器学习算法 二、监督学习和非监督学习 三、常见的机器学习概念解释 四、深度学习与机器学习的区别 基于Python 和 TensorFlow 深度学习框架实现简单的多层感知机&#xff08;MLP&#xff09;神经网络的示例代码&#xff1a; 欢迎三连哦&#xff01; 前言…

美团2024届秋招笔试第二场编程真题

要么是以0开头 要么以1开头 选择最小的答案累加 import java.util.Scanner; import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和…

批量高效剪辑视频,轻松调整视频时长,轻松打造完美节奏

在数字化时代&#xff0c;视频内容已成为我们生活中不可或缺的一部分。无论是社交媒体上的短视频&#xff0c;还是专业影视制作中的长片&#xff0c;视频剪辑都扮演着至关重要的角色。然而&#xff0c;面对大量视频素材&#xff0c;如何高效地进行剪辑调整&#xff0c;让每一帧…

临床数据采集痛点有哪些?怎样解决临床数据问题?

临床医学离不开数据采集&#xff0c;但想要得到高质量数据还是比较难&#xff0c;因为数据来源比较多&#xff0c;传统数据采集方式给临床医生带来诸多不便。 临床数据采集有哪些&#xff1f; 1、医院HIS、LIS系统 2、病案室档案和文件 3、医院信息科采集的数据 4、平时自…

cocos3.0资源管理

AssetBundle 官方文档&#xff1a;点击这里 资源缓存 官方文档&#xff1a;点击这里 引擎下载资源的逻辑如下&#xff1a;1.判断资源是否在游戏包内&#xff0c;如果在则直接使用&#xff1b;2.如果不在则查询资源是否在本地缓存中&#xff0c;如果在则直接使用&#xff1b;3.…

2024国自然状态 “已审核”代表什么?

2024年3月18日&#xff0c;16:00是今年国自然集中受理期项目的截止申报时间。 目前&#xff0c;已有多位申请人表示&#xff1a;提交的2024年国自然项目的状态&#xff0c;变成了已审核。 “已审核”代表啥&#xff1f; 图源&#xff1a;网络 申请人登录基金委ISIS系统&#…

LeetCode每日一题——移除链表元素

移除链表元素OJ链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 思路&#xff1a; 这与之前的移除元素的题目很相似&#xff0c;那么我们同样可以用类似的做法&#xff08;双指针&#xff09;进行解题。但是这是一个链表删除&a…

C语言回顾笔记

1.变量 2.运算符 3.if判断 4.接力break 5.最大公约数 6.水仙花数 #include<stdio.h> int main(){int n;scanf("%d",&n);//根据输入的位数计算&#xff0c;如最小三位数100 int first 1;int i 1;while(i<n){first *10;i; }printf("first%d\n"…

文献阅读笔记(Transformer)

文献阅读笔记&#xff08;Transformer&#xff09; 摘要Abstract1、文献阅读1.1 文献题目1.2 文献摘要1.3 研究背景1.4 模型架构1.4.1 Encoder-Decoder1.4.2 注意力机制1.4.3 多头注意力1.4.4 Position-wise Feed-Forward Networks1.4.5 Embeddings and Softmax1.4.6 Positiona…

【Linux】线程互斥{线程间的互斥相关背景概念/锁的相关问题/锁的原理/可重入VS线程安全}

文章目录 0.计算机如何完成y a * b c &#xff1f;1.线程间的互斥相关背景概念2.pthread_mutex_t3.pthread_mutex_lock()4.time() or gettimeofday5.锁的相关问题6.锁的原理7.可重入VS线程安全8.完善后的代码 0.计算机如何完成y a * b c &#xff1f; 来源&#xff1a; 王道…

【漏洞复现】netgear路由器 boarddataww 存在RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【Linux】详细分析/dev/loop的基本知识 | 空间满了的解决方法

目录 前言1. 基本知识2. 内存满了2.1 清空2.2 扩增 3. 彩蛋 前言 服务器一直down机&#xff0c;翻找日志文件一直找不到缘由&#xff0c;最终发现是挂载的内存满了&#xff0c;那本身这个文件就什么用呢&#xff1f; 1. 基本知识 /dev/loop是一种特殊的设备文件&#xff0c;…

Python JIT 编译器库之Pyjion使用详解

概要 Pyjion 是一个针对 Python 解释器的 JIT 编译器,旨在提高 Python 代码的性能。本文将深入探讨 Pyjion 库的特性、用法,并通过丰富的示例代码展示其在实际项目中的应用。 Pyjion 简介 Pyjion 是一个用于 Python 解释器的 JIT(即时编译)编译器,它的目标是通过实时编译…