Leetcode编程练习

news2024/9/23 15:19:12

面试题-消失的数字

. - 力扣(LeetCode)

class Solution 
{
public:
    void reverse(vector<int>& nums, int start, int end) 
    {
        while (start < end) 
        {
            swap(nums[start], nums[end]);
            start += 1;
            end -= 1;
        }
    }

    void rotate(vector<int>& nums, int k) 
    {
        // 防止被套圈
        k %= nums.size();

        // 先整体逆置
        reverse(nums, 0, nums.size() - 1);

        // 1. 将逆置到前面的逆置正常顺序
        reverse(nums, 0, k - 1);
        
        // 2. 将后面的也转换正常
        reverse(nums, k, nums.size() - 1);
    }
};
  1. 初始化:
    • int N = nums.size();:获取输入数组 nums 的大小,这表示从0到N-1的连续整数中应该有多少个数字。
    • int x = 0;:初始化一个变量 x,用于存储异或运算的结果。
  2. 第一个for循环:
    • 遍历数组 nums 中的每一个元素,并与 x 进行异或运算。
    • 因为异或运算的性质是:任何数与0异或都等于它本身;任何数与自身异或都等于0。所以,当遍历完数组后,x 中存储的是从0到N-1的所有整数与数组 nums 中实际存在的整数的异或结果。
  3. 第二个for循环:
    • 这个循环从0开始,到N(包括N)结束,与 x 进行异或运算。
    • 理想情况下,如果数组 nums 是完整的,即包含从0到N-1的所有整数,那么在这个循环结束后,x 的值应该是0(因为所有数字都异或了自己,结果为0)。
    • 但是,由于数组 nums 中缺失了一个数字,所以在这个循环结束后,x 的值将是缺失的那个数字(因为缺失的那个数字只被异或了一次,而其他数字都被异或了两次,结果为0)。
  4. 返回结果:
    • 最后,函数返回 x,即缺失的那个数字。

注意:第二个for循环中的 j 是从0遍历到 N(包括N),但实际上,当 j 等于 N 时,它并不与任何数组中的元素异或(因为数组索引是从0到N-1),但这并不影响结果,因为 N 与任何其他数字异或都会得到非零值(除非该数字也是 N,但这种情况不可能发生,因为数组中不可能有 N 这个元素)。

轮转数组

. - 力扣(LeetCode)

class Solution 
{
public:
    void reverse(vector<int>& nums, int start, int end) 
    {
        while (start < end) 
        {
            swap(nums[start], nums[end]);
            start += 1;
            end -= 1;
        }
    }

    void rotate(vector<int>& nums, int k) 
    {
        // 防止被套圈
        k %= nums.size();

        // 先整体逆置
        reverse(nums, 0, nums.size() - 1);

        // 1. 将逆置到前面的逆置正常顺序
        reverse(nums, 0, k - 1);
        
        // 2. 将后面的也转换正常
        reverse(nums, k, nums.size() - 1);
    }
};
  1. reverse 函数是一个辅助函数,用于反转数组 nums 中从索引 start 到 end(不包括 end)的部分。这个函数使用了双指针法,从两端开始交换元素,直到两个指针相遇或交叉。
  2. rotate 函数是主要的旋转函数。首先,它对 k 取模数组的长度 nums.size(),以确保 k 不会超出数组的范围。这是因为如果 k 大于数组的长度,那么实际上只需要旋转 k % nums.size() 次即可。
  3. 接下来,rotate 函数执行三次反转操作:
    • 第一次反转:对整个数组 nums 进行反转。这样,原本在末尾的 k 个元素现在就被移动到了数组的开头,但顺序是反的。
    • 第二次反转:对数组的前 k 个元素(索引从 0 到 k-1)进行反转。这样,原本在数组开头的 k 个元素(但顺序是反的)现在就被转回了正常顺序。
    • 第三次反转:对数组从索引 k 到末尾的部分进行反转。这样,剩余的元素也被转回了正常顺序。

经过这三次反转操作后,数组就被成功地旋转了 k 个位置。

这种方法的关键在于理解如何通过反转操作来重新排列数组中的元素。它避免了使用额外的空间,并且时间复杂度为 O(n),其中 n 是数组的长度。

回文链表

链表的回文结构_牛客题霸_牛客网

class PalindromeList
{
public:
    bool chkPalindrome(ListNode* A)
    {
        // 如果链表为空或者只有一个节点,那么它一定是回文的
        if (A == nullptr || A->next == nullptr)
            return true;

        // 快慢指针找出中间节点,slow 指针指向链表中间位置(如果链表长度是奇数,则指向中间节点;如果是偶数,则指向中间两个节点的第一个)
        ListNode* slow = A;
        ListNode* fast = A;
        while (fast != nullptr && fast->next != nullptr)
        {
            fast = fast->next->next;
            slow = slow->next;
        }

        // 反转后半部分链表,prev 指针指向反转后的链表头部
        ListNode* prev = nullptr;
        ListNode* curr = slow;

        while (curr != nullptr)
        {
            ListNode* temp = curr->next;
            curr->next = prev;
            prev = curr;
            curr = temp;
        }

        // 检查回文,p1 指针指向链表头部,p2 指针指向反转后的链表头部
        ListNode* p1 = A;
        ListNode* p2 = prev;
        while (p1 != nullptr && p2 != nullptr)
        {
            // 如果节点值不相等,则链表不是回文的
            if (p1->val != p2->val)
            {
                return false;
            }
            p1 = p1->next;
            p2 = p2->next;
        }

        // 链表是回文的
        return true;
    }
};

找中间节点

// 快慢指针找出中间节点,slow 指针指向链表中间位置(如果链表长度是奇数,则指向中间节点;如果是偶数,则指向中间两个节点的第一个)
    ListNode* slow = A;
    ListNode* fast = A;
    while (fast != nullptr && fast->next != nullptr)
    {
        fast = fast->next->next;
        slow = slow->next;
    }

定义了两个指针 slow 和 fast,初始时它们都指向链表的头部。在循环中,fast 指针每次向前移动两步,而 slow 指针每次向前移动一步。当 fast 指针到达链表的末尾时,slow 指针就会指向链表的中间位置。

  • 该步骤用来分割链表,以便后续操作

反转后半链表

// 反转后半部分链表,prev 指针指向反转后的链表头部
        ListNode* prev = nullptr;
        ListNode* curr = slow;

        while (curr != nullptr)
        {
            ListNode* temp = curr->next;
            curr->next = prev;
            prev = curr;
            curr = temp;
        }

就是将后半部分的链表每个节点next指向前一个节点,这样就形成了反转链表,链表头是翻转前的最后一个节点。
值得注意:前半部分的最后一个节点的next还是指向翻转前的后半部分第一个节点(也就是后半部分反转后的最后一个节点),所以在后续进行判断两个链表是否相同的时候直接向后进行判断就可以。

检查两个链表

        // 检查回文,p1 指针指向链表头部,p2 指针指向反转后的链表头部
        ListNode* p1 = A;
        ListNode* p2 = prev;
        while (p1 != nullptr && p2 != nullptr)
        {
            // 如果节点值不相等,则链表不是回文的
            if (p1->val != p2->val)
            {
                return false;
            }
            p1 = p1->next;
            p2 = p2->next;
        }

        // 链表是回文的
        return true;
    }

使用一个循环来比较两个指针所指向的节点值。如果发现任何一个节点值不相等,就意味着链表不是回文的,我们直接返回 false。如果循环完成后都没有发现不相等的节点值,那么链表就是回文的,我们返回 true。

相交链表

class Solution 
{
public:
    ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) 
    {
        if (headA == nullptr || headB == nullptr) 
        {
            return nullptr;
        }
        ListNode* pA = headA, * pB = headB;

        // 如果有交点,那么在第一次相同的时候就会返回pa
        while (pA != pB) 
        {
            pA = pA == nullptr ? headB : pA->next;
            pB = pB == nullptr ? headA : pB->next;
        }
        // 换道思想,如果两个链表长度不同,可以理解为补长度,
        // 然后重新回到另一个链表的头的那个长度和和另一个指针指向剩余的长度相同,然后就可以达到一个相同的交点
        return pA;
    }
};

对于以下代码可能理解的时候存在一些误区,所以我作出以下思路整理:

        while (pA != pB) 
        {
            pA = pA == nullptr ? headB : pA->next;
            pB = pB == nullptr ? headA : pB->next;
        }
        // 换道思想,如果两个链表长度不同,可以理解为补长度,
        // 然后重新回到另一个链表的头的那个长度和和另一个指针指向剩余的长度相同,然后就可以达到一个相同的交点
        return pA;

image.png

  1. 假设链表 A 和链表 B 的长度不同,我们让指针从另一个链表的头部重新开始遍历,实际上就是将短链表的指针向前移动了长度差的距离,以此来“补齐长度”。
  2. 当两个指针再次开始从头部出发时,它们之间的距离就会相等,这时它们就像在同一起跑线上开始了新的竞赛。
  3. 当两个指针在两个链表中遍历时,它们会同时移动相同的步数。这样,当它们到达交点时,它们就会处于相同的位置,即使两个链表的长度不同。

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

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

相关文章

IPD-开发流程

2024-5-6记录于PR办公室 在上一家公司做硬件产品经理的时候&#xff0c;Richard Li曾花费“巨资”请了华为前战略专家给我们培训&#xff0c;讲授IPD这门课的模式都很IPD&#xff0c;当时完全没重视&#xff0c;光想着不可能靠这个能把产品做好&#xff0c;这样做产品必定是一批…

RS2057XH功能和参数介绍及规格书

RS2057XH 是一款由润石科技&#xff08;Runic Semiconductor&#xff09;生产的模拟开关芯片&#xff0c;其主要功能和参数如下&#xff1a; 产品特点&#xff1a; 低电压操作&#xff1a;支持低至1.8V的工作电压&#xff0c;适用于低功耗应用。 高带宽&#xff1a;具有300MHz的…

Matlab 手写板设计

1、介绍 MATLAB手写板可以作为一个很好的数据输入口&#xff0c;其可以获取该手写板上任意字母、数字&#xff0c;甚至可以制作样本数据。具体用途体现在如下几方面&#xff1a; 数学公式输入&#xff1a;手写板允许用户直接用手写方式输入复杂的数学公式&#xff0c;这对于使…

C/C++ BM32 合并二叉树

文章目录 前言题目解决方案一1.1 思路阐述1.2 源码 解决方案二2.1 思路阐述2.2 源码 总结 前言 树的题目大概率是要用到递归的&#xff0c;将一个树的问题拆分成子树的问题&#xff0c;不断拆分。 这题也用到了递归的思想。 题目 已知两颗二叉树&#xff0c;将它们合并成一颗…

基于springboot+vue+Mysql的租房网站

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Java17 --- SpringCloud之Nacos

目录 一、下载nacos并运行 1.1、创建9001微服务作为提供者 1.2、创建80微服务作为消费者 二、naocs配置中心规则与动态刷新 2.1、创建3377微服务 2.2、在nacos中创建配置文件 三、nacos数据模型之Namespace-Group-Datald 3.1、DatalD方案 3.2、Group方案 3.3、Name…

产业观察:电机驱动成为人形机器人的动力核心

前不久&#xff0c;波士顿动力发布一则“再见&#xff0c;液压Atlas”视频&#xff0c;宣告其著名的液压驱动双足人形机器人Atlas正式退役。这则视频引起全球所有Atlas粉丝的高度关注。然而紧接着&#xff0c;波士顿动力便又推出了全部由电机驱动的新一代Atlas机器人&#xff0…

数据结构相关

数据结构相关 文章目录 数据结构相关[TOC](文章目录)前言一、数据结构介绍二、不同的逻辑结构的存储方案(Java实现)2.1 线性结构&#xff1a;线性表、数组2.2 线性结构&#xff1a;栈2.3 线性结构&#xff1a;队列2.4 树形结构&#xff1a;树 三、一些常见的3.1 布隆过滤器Bloo…

自动化工具

一、介绍一些自动化的工具 puppet和chef用的是Ruby语言http协议&#xff0c;淘汰 saltstack Python语言 c/s ssh协议&#xff0c;5% ansible 无cilent ssh协议 用Python开发 95% 二、ansible简介 2.1 ansible自动化运维工具特点 Ansible 与 Saltstack 均是基于…

Day_1

1. 环境搭建 技术选型 后端项目结构 sky-take-out maven父工程&#xff0c;统一管理依赖版本&#xff0c;聚合其他子模块 sky-common 子模块&#xff0c;存放公共类&#xff0c;例如&#xff1a;工具类、常量类、异常类等 sky-pojo 子模块&#xff0c;存放实体类、VO、DTO…

【爬虫】爬取A股数据写入数据库(一)

1. 对东方财富官网的分析 步骤&#xff1a; 通过刷新网页&#xff0c;点击等操作&#xff0c;我们发现https://datacenter-web.eastmoney.com/api/data/v1/get?请求后面带着一些参数即可以获取到相应数据。我们使用python来模拟这个请求即可。 我们以如下选择的页面为切入点…

GiantPandaCV | FasterTransformer Decoding 源码分析(三)-LayerNorm介绍

本文来源公众号“GiantPandaCV”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;FasterTransformer Decoding 源码分析(三)-LayerNorm介绍 作者丨进击的Killua 来源丨https://zhuanlan.zhihu.com/p/669440844 编辑丨GiantPandaC…

ollama + Anythingllm的安装

Ollama官网&#xff1a;https://ollama.com Anythingllm 官网下载&#xff1a;https://useanything.com/download 在Linux下如果直接运行./AnythingLLMDesktop.AppImage 报错的话&#xff0c;可以尝试以下命令&#xff1a; ./AnythingLLMDesktop.AppImage --appimage-extract …

微信公众号排名 SEO的5个策略

随着微信公众号在社交媒体领域的持续发展和普及&#xff0c;如何提升公众号的搜索排名&#xff0c;成为许多运营者关注的焦点。公众号排名SEO&#xff0c;即针对微信公众号进行搜索引擎优化&#xff0c;旨在提高公众号在搜索结果中的曝光率和点击率。下面&#xff0c;我们将深入…

什么是期货?期货的基础知识有哪些?

期货是一种标准化的远期合约&#xff0c;允许买卖双方在未来特定时间以预定价格交易货物或金融资产。也是一种金融衍生品&#xff0c;它为市场参与者提供了一种管理价格波动风险和进行投资的工具。 期货的基础知识有哪些 期货市场是一个复杂的金融环境&#xff0c;对于初学者来…

系统镜像地址

系统镜像 Linux 官网下载地址&#xff1a;Downloadhttps://www.centos.org/download/ 阿里云镜像下载地址&#xff1a;https://mirrors.aliyun.com/centos/https://mirrors.aliyun.com/centos/?spma2c6h.13651104.d-2001.6.6554320cwFqB8E 清华大学镜像下载地址&#xff1…

你对AI的所有疑虑,厚德云替你解答!

遇到难题不要怕&#xff01;厚德提问大佬答&#xff01; 厚德提问大佬答 你是否对AI绘画感兴趣却无从下手&#xff1f;是否有很多疑问却苦于没有大佬解答带你飞&#xff1f;从此刻开始这些问题都将迎刃而解&#xff01;你感兴趣的话题&#xff0c;厚德云替你问&#xff0c;你解…

原型图制作神器!6款软件推荐,助你轻松实现设计构想!

在现代设计领域&#xff0c;原型图的制作是一个至关重要的环节。它们帮助设计师将创意转化为可视化界面&#xff0c;评估用户体验并进行交互测试。本文将介绍六款备受推崇的原型图软件&#xff0c;它们以强大的功能、易用的界面和灵活的工作流程脱颖而出&#xff0c;为设计师创…

每日算法-java

题目来自蓝桥云 // 这是一个Java程序&#xff0c;用于解决最长不下降子序列问题。 // 问题描述&#xff1a;给定一个整数序列&#xff0c;找到最长的子序列&#xff0c;使得这个子序列是不下降的&#xff08;即相邻的元素不严格递减&#xff09;。 // 程序使用了动态规划的方法…

Redis 渐进式遍历 -- scan

前言 keys 可以一次性把 Redis 中的所有 key 都获取到&#xff0c;但这个操作比较危险&#xff0c;一次性获取所有的key 很容易会导致 Redis 阻塞。 而通过渐进式遍历&#xff08;不是一个命令就将所有的 key 值拿到&#xff0c;而是每执行一次命令只获取其中的一小部分&#x…