LeetCode 热题 HOT 100(P1~P10)

🔥 LeetCode 热题 HOT 100

这里记录下刷题过程中的心得,其实算法题基本就是个套路问题,很多时候你不知道套路或者模板,第一次尝试去做的时候就会非常懵逼、沮丧和无助。而且就算你一时理解并掌握了,过一段时间往往会绝望的发现你又不会了。所以过遍数就非常重要,我目前配合 anki  来复习。

 LC001two_sum 两数之和(简单)

. - 力扣(LeetCode)

题目:

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

解法:

使用HashMap 是比较常规的解法,这里有个技巧是只通过一遍循环就能解决问题。从头开始遍历,然后顺便把元素放入HashMap,这样就不用先遍历一遍初始化HashMap。

public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> cache = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int value = target - nums[i];
            if (cache.containsKey(value)) {
                return new int[]{ i, cache.get(value) };
            }
            cache.put(nums[i], i);
        }
        return null;

    }

LC002add_two_numbers 两数相加(中等)

题目:

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

解法:

链表题通常的操作是先增加一个前置pre 节点,这样就能大大方便后续的操作。因为最后你要返回头节点,这个时候pre.next 就是。

这道题核心难点是对进位的处理,因此需要有一个变量表示每次的进位,同时在最后还要对进位进行判断,这点特别容易遗漏。剩下的就是一些细节的处理,有一些为null 的情况需要处理,这点也非常容易踩坑。

 public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        //表示进位
        int carry = 0;
        while (l1 != null || l2 != null) {
            int left = l1 == null ? 0 : l1.val;
            int right = l2 == null ? 0 : l2.val;

            int sum = left + right + carry;
            carry = sum / 10;
            sum = sum % 10;
            cur.next = new ListNode(sum);
            cur = cur.next;

            l1 = l1 == null ? null : l1.next;
            l2 = l2 == null ? null : l2.next;
        }
        if (carry == 1) {
            cur.next = new ListNode(carry);
        }
        return pre.next;
    }

LC003longest_substring 无重复字符的最长子串 (中等)

. - 力扣(LeetCode)

题目:

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度

解法:

典型的滑动窗口策略,窗口的左右下标刚开始都是0,首先需要一个缓存用于存放已经遍历过的字符。右下标开始遍历,并跟缓存中的字符比较,存在就说明遇到重复的了,这个时候左右下标构成的字符串就是非重复的字符串,然后当前元素进缓存,左下标往前。这里需要注意要设置一个起始点,在每次判断更新最大长度的时候需要记录下这个起始点下标,不然最后输出的时候没办法定位。

public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> cache = new HashMap<>();
        int left = 0, max = 0;
        for (int i = 0; i < s.length(); i++) {
            final char key = s.charAt(i);
            if (cache.containsKey(key)) {
                // 这里+1 说明遇到重复字母,left 标往前挪动了一位
                left = Math.max(left, cache.get(key) + 1);
            }
            cache.put(key, i);
            max = Math.max(max, i - left + 1);
        }
        return max;
    }

这里有个优化性能的小技巧,因为字符由由英文字母、数字、符号和空格组成,因此可以用asc2 表示,这样可以用int[128] 代替HashMap。

LC004median_of_two 寻找两个正序数组的中位数 (困难)

. - 力扣(LeetCode)

题目:

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。

算法的时间复杂度应该为 O(log (m+n)) 。

解法:

难点在于复杂度要求为log,这个典型折半查找的思路了。

根据中位数的定义,当 m+n是奇数时,中位数是两个有序数组中的第 (m+n)/2 个元素,当 m+n 是偶数时,中位数是两个有序数组中的第 (m+n)/2 个元素和第 (m+n)/2+1 个元素的平均值。因此,这道题可以转化成寻找两个有序数组中的第 k 小的数,其中 k 为 (m+n)/2 或 (m+n)/2+1。

剩下的问题就是怎么在两个数组中找第k个数,并且还要是log 的复杂度。这里直接给结论,先比较两个数组中k/2 位置的2个数,小的那一个所在数组前k/2 就可以舍弃了,同样的思路接着找剩下的k/2,当然这里有很多细节和边界需要考虑。

public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int length1 = nums1.length, length2 = nums2.length;
        int totalLength = length1 + length2;
        //个数为奇数的情况
        if (totalLength % 2 == 1) {
            int midIndex = totalLength / 2;
            double median = getKthElement(nums1, nums2, midIndex + 1);
            return median;
        } else {
            //个数偶数的情况
            int midIndex1 = totalLength / 2 - 1, midIndex2 = totalLength / 2;
            double median =
                    (getKthElement(nums1, nums2, midIndex1 + 1) + getKthElement(nums1, nums2, midIndex2 + 1)) / 2.0;
            return median;
        }
    }

    /**
     * 注意这里的k是第k位,并不是下标k
     *
     * @param nums1
     * @param nums2
     * @param k
     * @return
     */
    public int getKthElement(int[] nums1, int[] nums2, int k) {
        /* 主要思路:要找到第 k (k>1) 小的元素,那么就取 pivot1 = nums1[k/2-1] 和 pivot2 = nums2[k/2-1] 进行比较
         * 这里的 "/" 表示整除
         * nums1 中小于等于 pivot1 的元素有 nums1[0 .. k/2-2] 共计 k/2-1 个
         * nums2 中小于等于 pivot2 的元素有 nums2[0 .. k/2-2] 共计 k/2-1 个
         * 取 pivot = min(pivot1, pivot2),两个数组中小于等于 pivot 的元素共计不会超过 (k/2-1) + (k/2-1) <= k-2 个
         * 这样 pivot 本身最大也只能是第 k-1 小的元素
         * 如果 pivot = pivot1,那么 nums1[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums1 数组
         * 如果 pivot = pivot2,那么 nums2[0 .. k/2-1] 都不可能是第 k 小的元素。把这些元素全部 "删除",剩下的作为新的 nums2 数组
         * 由于我们 "删除" 了一些元素(这些元素都比第 k 小的元素要小),因此需要修改 k 的值,减去删除的数的个数
         */

        int length1 = nums1.length, length2 = nums2.length;
        int index1 = 0, index2 = 0;

        while (true) {
            // 边界情况
            if (index1 == length1) {
                return nums2[index2 + k - 1];
            }
            if (index2 == length2) {
                return nums1[index1 + k - 1];
            }
            if (k == 1) {
                return Math.min(nums1[index1], nums2[index2]);
            }

            // 正常情况
            int half = k / 2;
            int newIndex1 = Math.min(index1 + half, length1) - 1;
            int newIndex2 = Math.min(index2 + half, length2) - 1;
            int pivot1 = nums1[newIndex1], pivot2 = nums2[newIndex2];
            if (pivot1 <= pivot2) {
                k -= (newIndex1 - index1 + 1);
                index1 = newIndex1 + 1;
            } else {
                k -= (newIndex2 - index2 + 1);
                index2 = newIndex2 + 1;
            }
        }
    }

getKthElement 可以用递归的方法改写下,这样能精简不少。

LC005longest_palindromic 最长回文子串 (中等)

. - 力扣(LeetCode)

题目:

给你一个字符串 s,找到 s 中最长的回文子串。如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

解法:

这里用了动态规划,动态规划的难点在于动态方程的推导,动态方程很多时候又取决于动态数组的定义,只能说多接触不同类型的题目来增长这方面的经验。

针对这道题定义了boolean 类型的2维数组,dp[i][j] 表示s[i][j]是否为回文。

然后就是2层循环不断推进的过程。

public String longestPalindrome(String s) {
        final int len = s.length();
        if (len < 2) {
            return s;
        }
        int begin = 0, max = 1;

        //dp[i][j] 表示s[i][j]是否为回文
        boolean[][] dp = new boolean[len][len];
        final char[] charArray = s.toCharArray();
        for (int j = 0; j < len; j++) {
            for (int i = 0; i <= j; i++) {
                if (charArray[j] == charArray[i]) {
                    //只有3个的时候,只要两边相等就是回文
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        //大于3个的时候就要看进一步的情况
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                //如果是回文就看下是否当前最大
                if (dp[i][j] && j - i + 1 > max) {
                    begin = i;
                    max = j - i + 1;
                }
            }
        }
        return s.substring(begin, begin + max);
    }
理解了核心思想之后,其实就是一些套路了。

LC011container_with 盛最多水的容器 (中等)

. - 力扣(LeetCode)

题目:

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。

解法:

套路题,用双指针左右夹逼法求解。一开始左右指针在两边头尾,这个时候宽度是最大的,高是两边最矮的那个,然后进一步从矮的那边往中间靠近。

public int maxArea(int[] height) {
        int left = 0, right = height.length - 1;
        int max = 0;

        while (left < right) {
            int high = Math.min(height[left], height[right]);
            int wide = right - left;
            max = Math.max(max, high * wide);
            if (height[left] < height[right]) {
                left++;
            } else {
                right--;
            }
        }
        return max;
    }

未完待续

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

#WEB前端(CSS基础)

1.实验&#xff1a;HTML是网页骨架&#xff0c;CCS是网页装修 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; style 4.代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"view…

为什么模电这么难学?这是我见过最好的回答

大家好&#xff0c;我是砖一&#xff0c;有很多人抱怨模电难学&#xff0c;被誉为电子信息挂科率最高之一&#xff0c;下面听我分析一下为啥模电这么难学&#xff1f; 01 理科的抽象思维 在高等教育体系中&#xff0c;模电是涉及半导体方向的第一门工程类课程&#xff0c;是一…

Unity中URP下实现水体(C#动态生成渐变图)

文章目录 前言一、Shader部分1、申明水渐变图纹理和采样器2、在片元着色器&#xff0c;进行纹理采样&#xff0c;并且输出 二、C#脚本部分1、我们新建一个C#脚本2、我们定义两个变量3、在Start内&#xff0c;new 一个Texture2D(宽&#xff0c;高)4、定义一个Color[宽*高]的颜色…

Flink状态存储-StateBackend

文章目录 前言一、MemoryStateBackend二、FSStateBackend三、RocksDBStateBackend四、StateBackend配置方式五、状态持久化六、状态重分布OperatorState 重分布KeyedState 重分布 七、状态过期 前言 Flink是一个流处理框架&#xff0c;它需要对数据流进行状态管理以支持复杂的…

25高数考研张宇 -- 公式总结(更新中)

1. 两个重要极限 (1) lim ⁡ x → 0 sin ⁡ x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0​xsinx​1, 推广形式 lim ⁡ f ( x ) → 0 sin ⁡ f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0​f(x)sinf(x)​1. (2) lim ⁡…

电子电器架构 —— DoIP协议相关的介绍

电子电器架构 —— DoIP协议相关的介绍 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他人的角度来反对自己。人生在世,最怕…

BEVFusion

1. 简介 融合激光雷达和相机的信息已经变成了3D目标检测的一个标准&#xff0c;当前的方法依赖于激光雷达传感器的点云作为查询&#xff0c;以利用图像空间的特征。然而&#xff0c;人们发现&#xff0c;这种基本假设使得当前的融合框架无法在发生 LiDAR 故障时做出任何预测&a…

U盘弹出提示“该设备正在使用中”:原因与解决方案

在日常使用U盘时&#xff0c;我们可能会遇到一个问题&#xff1a;当尝试安全弹出U盘时&#xff0c;系统提示“该设备正在使用中”。这种情况可能会让用户感到困惑&#xff0c;担心数据是否安全或是否会导致U盘损坏。本文旨在探讨这一现象背后的原因&#xff0c;并提供相应的解决…

Python 自动化给女友发邮件:含新闻、天气、每日一句、图片 最全攻略系列02 如何添加emoji

Python 自动化给女友发邮件:含新闻、天气、每日一句、图片 最全攻略系列 是否想在女友面前展示程序员炫酷的一面? 是否想给她每日问候但是害怕忘记固定时间发送信息? 是否也羡慕别人可以优雅使用Python定时发送邮件? 欢迎来到Python自动化发邮件最全攻略系列,本系列将…

软考54-上午题-【数据库】-关系模式的范式-真题

一、范式总结 第一步&#xff0c;先求候选码&#xff0c;由此得到&#xff1a;主属性、非主属性。 二、判断部分函数依赖的技巧 【回顾】&#xff1a;部分函数依赖 &#xff08;X&#xff0c;Y&#xff09;——>Z&#xff1b; X——>Z 或者 Y——>Z 题型&#xff1a;给…

对单元测试的思考(稳定性建设)

单测是很常见的技术的名词&#xff0c;但背后的逻辑和原理你是否清楚&#xff0c;让我们一起review一下。 1. 单测是什么&#xff1f;&#x1f914; 单测是单元测试,主要是测试一个最小逻辑块。比如一个函数、一个react、vue 组件。 2.为什么要写单测&#xff1f;&#x1f9…

《Large Language Models for Generative Information Extraction: A Survey》阅读笔录

论文地址&#xff1a;Large Language Models for Generative Information Extraction: A Survey 前言 映像中&#xff0c;比较早地使用“大模型“”进行信息抽取的一篇论文是2022年发表的《Unified Structure Generation for Universal Information Extraction》&#xff0c;也…

c++基础知识补充4

单独使用词汇 using std::cout; 隐式类型转换型初始化&#xff1a;如A a1,,此时可以形象地理解为int i1;double ji;&#xff0c;此时1可以认为创建了一个值为1的临时对象&#xff0c;然后对目标对象进行赋值&#xff0c;当对象为多参数时&#xff0c;使用&#xff08;1&#xf…

2024最新算法:电鳗觅食优化算法(Electric eel foraging optimization,EEFO)求解23个基准函数(提供MATLAB代码)

一、电鳗觅食优化算法 电鳗觅食优化算法&#xff08;Electric eel foraging optimization,EEFO&#xff09;由Weiguo Zhao等人提出的一种元启发算法&#xff0c;EEFO从自然界中电鳗表现出的智能群体觅食行为中汲取灵感。该算法对四种关键的觅食行为进行数学建模&#xff1a;相…

2000-2021年各省互联网普及率数据

2000-2021年各省互联网普及率数据 1、时间&#xff1a;2000-2021年 2、指标&#xff1a;省级&#xff1a;行政区划代码、地区、年份、互联网普及率(%) 3、来源&#xff1a;互联网络信息中心&#xff1b;各地统计局 4、指标解释&#xff1a;指互联网用户数占常住人口总数的比…

环形链表详解(让你彻底理解环形链表)

文章目录 一.什么是环形链表&#xff1f;二.环形链表的例题&#xff08;力扣&#xff09; 三.环形链表的延伸问题 补充 一.什么是环形链表&#xff1f; 环形链表是一种特殊类型的链表数据结构&#xff0c;其最后一个节点的"下一个"指针指向链表中的某个节点&#xff…

【tableau学习笔记】tableau无法连接数据源

【tableau学习笔记】tableau无法连接数据源 背景&#xff1a; 学校讲到Tableau&#xff0c;兴奋下载Kaggle Excel&#xff0c;一看后缀CSV&#xff0c;导入Tableau发现报错“tableau无法连接数据源”&#xff0c;自作聪明改为后缀XLSX&#xff0c;bug依旧。 省流&#xff1a…

QML中动态表格修改数据

1.qml文件中的实现代码 import QtQuick 2.15 import QtQuick.Window 2.15import QtQuick.Controls 2.0 import Qt.labs.qmlmodels 1.0 import QtQuick.Layouts 1.15Window {width: 640height: 480visible: truetitle: qsTr("Hello World")TableModel{id:table_model…

【风格迁移】URST:解决超高分辨率图像的风格迁移问题

URST&#xff1a;解决超高分辨率图像的风格迁移问题 提出背景URST框架的整体架构 提出背景 论文&#xff1a;https://arxiv.org/pdf/2103.11784.pdf 代码&#xff1a;https://github.com/czczup/URST?v1 有一张高分辨率的风景照片&#xff0c;分辨率为1000010000像素&#…