剑指offer刷题笔记--Num21-30

news2024/9/26 3:29:33

1--调整数组顺序使奇数位于偶数前面(21)

主要思路:

        双指针法,左指针从 0 开始遍历,直到遇到偶数,右指针从 len - 1 开始遍历,直到遇到奇数;

        这时左指针指向偶数,右指针指向奇数,交换两个指针的数值,并继续判断下一组数;

#include <iostream>
#include <vector>

class Solution {
public:
    std::vector<int> exchange(std::vector<int>& nums) {
        if (nums.empty()){
            return nums;
        }
        int len = nums.size();
        int l = 0;
        int r = len - 1;
        int temp;
        while(l < r){
            while(l < len && nums[l] % 2 != 0){ // 为奇数,直到遇到偶数
                l++;
            }
            while(r > 0 && nums[r] % 2 == 0){ // 为偶数,直到遇到奇数
                r--;
            }

            if(l == len || r == 0) break; // 防止全是奇数或者全是偶数,导致溢出

            // 交换左右指针的数
            if(l < r){
                temp = nums[l];
                nums[l] = nums[r];
                nums[r] = temp;
            }
            // 交换后判断下一组数
            l++;
            r--;
        }
        return nums;
    }
};

int main(int argc, char *argv[]){
    // std::vector<int> nums = {1, 2, 3, 4};
    std::vector<int> nums = {1, 11, 14};
    Solution s1;
    s1.exchange(nums);
    for(int item : nums){
        std::cout << item << " ";
    }
    return 0;
}

2--链表中倒数第 k 个节点(22)

 主要思路:

        双指针法,先让右指针移动 k 步,接着左右指针同时移动;

        当右指针指向 NULL 时,结束遍历;由于左右指针的间距为k,则左指针指向原链表的倒数第 k 个节点,直接返回即可;

#include <iostream>
#include <vector>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode *left = head;
        ListNode *right = head;
        for(int i = 0; i < k; i++){
            right = right->next;
        }
        while(right != NULL){
            left = left->next;
            right = right->next;
        }
        return left;
    }
};

int main(int argc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);
    ListNode *Node5 = new ListNode(5);
    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;
    int k = 2;

    Solution s1;
    ListNode* head = s1.getKthFromEnd(Node1, k);
    while(head != NULL){
        std::cout << head->val << std::endl;
        head = head->next;
    }
    return 0;
}

3--反转链表(24)

主要思路:

        想象成环形链表,反转链表的实质上结点指向上一个结点,则只需遍历链表,将当前结点指向上一个结点,不断更新当前结点和上一个结点即可;

#include <iostream>
#include <vector>

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if (head == NULL) return head;
        ListNode *cur = head;
        ListNode *pre = NULL; // 前一个结点初始化为 null
        while(cur != NULL){
            ListNode *tmp = cur->next; // 记录下一个结点
            cur->next = pre; // 当前结点指向上一个结点
            pre = cur; // 更新上一个结点为当前结点
            cur = tmp; // 更新当前结点为记录的下一个结点
        }
        return pre;
    }
};

int main(int argc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(3);
    ListNode *Node4 = new ListNode(4);
    ListNode *Node5 = new ListNode(5);
    Node1->next = Node2;
    Node2->next = Node3;
    Node3->next = Node4;
    Node4->next = Node5;

    Solution s1;
    ListNode *head = s1.reverseList(Node1);
    while(head != NULL){
        std::cout << head->val << " ";
        head = head->next;
    }

    return 0;
}

4--合并两个排序的链表(25)

主要思路:

        逐个比较两个链表的元素,归并到新的链表中;

#include <iostream>

struct ListNode {
     int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode *L = new ListNode(0);
        ListNode *last = L;
        ListNode *head1 = l1;
        ListNode *head2 = l2; 
        while(head1 != NULL && head2 != NULL){
            if(head1->val <= head2->val){
                last->next = head1;
                head1 = head1->next;
            }
            else{
                last->next = head2;
                head2 = head2->next;
            }
            last = last->next;
        }
        if(head1 == NULL) last->next = head2;
        if(head2 == NULL) last->next = head1;

        return L->next;
    }
};

int main(int argc, char *argv[]){
    ListNode *Node1 = new ListNode(1);
    ListNode *Node2 = new ListNode(2);
    ListNode *Node3 = new ListNode(4);
    Node1->next = Node2;
    Node2->next = Node3;

    ListNode *Node4 = new ListNode(1);
    ListNode *Node5 = new ListNode(3);
    ListNode *Node6 = new ListNode(4);
    Node4->next = Node5;
    Node5->next = Node6;

    Solution s1;
    ListNode *L = s1.mergeTwoLists(Node1, Node4);

    while(L != NULL){
        std::cout << L->val << " ";
        L = L->next;
    }

    return 0;
}

5--树的子结构(26)

主要思路:

        B 是 A 的子结构,则 B 的根节点必和 A 的某一个结点相同;

        当找到与 B 根节点相同的 A 结点后,需要递归判断其左右子树是否相同;

        递归终止条件:B 为空,表明B的所有数据都判断完毕,返回 true;A 为空 或 A 的值不等于 B 的值,返回 false;

#include <iostream>

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution {
public:
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(A == NULL || B == NULL) return false;

        // B 可能存在于 A 的左子树或右子树中
        return dec(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
    }

    bool dec(TreeNode* A, TreeNode* B){
        if(B == NULL){ // B 为空,表明B的所有数据都判断完毕,返回 true
            return true;
        }
        if(A == NULL || A->val != B->val){ // A 为空,或 A 的值不等于 B 的值,返回false
            return false;
        }
        // A 的值等于 B 的值,还需判断 A 的左子树和 B 的左子树,A 的右子树和 B 的右子树
        return dec(A->left, B->left) && dec(A->right, B->right);
    }
};

int main(int argc, char *argv[]){
    TreeNode *Node1 = new TreeNode(3);
    TreeNode *Node2 = new TreeNode(4);
    TreeNode *Node3 = new TreeNode(5);
    TreeNode *Node4 = new TreeNode(1);
    TreeNode *Node5 = new TreeNode(2);

    Node1->left = Node2;
    Node1->right = Node3;
    Node2->left = Node4;
    Node2->right = Node5;
    
    TreeNode *Node6 = new TreeNode(4);
    TreeNode *Node7 = new TreeNode(1);
    Node6->left = Node7;

    Solution s1;
    bool res = s1.isSubStructure(Node1, Node6);
    if (res) std::cout << "true" << std::endl;
    else std::cout << "false" << std::endl;

    return 0;
}

6--二叉树的镜像(27)

 

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

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

相关文章

kube-proxy源码阅读

kube-proxy源码阅读 通过阅读kube-proxy的源码可以将proxy的主要逻辑总结为下图所示&#xff1a; 首先顺着代码阅读到ProxyServer->Run()函数&#xff0c;这里是kube-proxy启动的主逻辑&#xff0c;启动了两个server&#xff0c;分别是&#xff1a; ...var errCh chan err…

基于深度学习的高精度安全帽背心检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度安全帽背心检测识别系统可用于日常生活中或野外来检测与定位安全帽背心目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的安全帽背心目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用…

【软考网络管理员】2023年软考网管初级常见知识考点(18)-安全协议SSL与PGP、数据加密技术

涉及知识点 安全套接层协议SSL详解&#xff0c;PGP协议是什么&#xff1f;数据加密技术有哪些&#xff1f;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多考点…

JUC之LockSupport和中断

文章目录 1 线程中断机制1.1 什么是线程中断机制1.2 三大中断方法1.3 如何中断运行中的线程1.3.1 通过volatile变量实现1.3.1 通过AtomicBoolean实现1.3.1 通过interrupt和isInterrupted api实现 2 LockSupport2.1 为什么会出现LockSupport2.2 两道面试题 参考材料 1 线程中断机…

案例合集 | 创新社会组织服务,打造“数字化商协会”

数字化建设方兴未艾数字化商会势在必行 近年来&#xff0c;国务院、发改委等机构陆续出台了一系列鼓励数字经济与产业数字化发展的规划指南&#xff0c;内容主要涵盖鼓励平台经济建设、促进供应链数字化转型与提升中小企业数字化渗透等方面&#xff0c;顶层政策引导并促进企业…

使用Gradio的BarPlot模块创建交互式柱状图

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

SQL和NoSQL数据库的便捷速查表

在项目成功的过程中选择合适的数据库非常重要。以下是关键要点的总结&#xff1a; •SQL数据库提供结构化数据存储、SQL支持和关系能力。•NoSQL数据库提供灵活性、可扩展性和分布式架构。•专门的数据库&#xff0c;如列存储、图形数据库、空间数据库和时间序列数据库&#xf…

Jetpack compose中实现流畅的Theme选择器动画

Jetpack compose中实现流畅的Theme Picker动画 Jetpack Compose改变了我们在Android上管理主题的方式。它提供了更大的灵活性&#xff0c;使我们能够以更多的方式定义用户界面&#xff08;UI&#xff09;。此外&#xff0c;Compose中的动画系统使我们能够轻松创建令人印象深刻和…

如何训练全自动的安卓ai脚本(yolov5 为例) 实现游戏应用自动屏幕识别点击

必要资源 yolo训练方法&#xff0c;调参要点:https://docs.ultralytics.com/ncnn yolov5 示例:https://github.com/nihui/ncnn-android-yolov5在线模型转换&#xff1a;https://convertmodel.com/ 硬件配备 32G 内存, 2060 英伟达显卡 操作步骤 1.准备好数据集&#xff0c…

管理类联考——逻辑——知识篇——形式逻辑——五、联言选言——haimian

联言&选言 考点分析 考点分析 削弱 年度 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023题量6222111 联言 本质定义 联言命题是断定两种或两种以上事物情况同时存在的命题&#xff0c;用“A并且B”表示&#xff0c;逻辑符号为A ∧ B。 若“A ∧ B”为真…

为什么uCOSii的栈顶不再是0x20000000

我将FreeRTOS的工程文件移植到基于uCOSii系统中&#xff0c;发现两个系统生成的栈顶地址不一样&#xff0c;即使栈的大小相同&#xff0c;都是用Keil编译器&#xff0c;差别很大。见下图&#xff1a; Stack_Size EQU 0x00001000; 以前一直使用FreeRTOS系统&#xff0c…

简单易懂:Vue3框架三天速成(一)

前言&#xff1a;学习Vue框架首先需要具备基本的HTML5、CSS3、JavaScript基础&#xff0c;了解基本概念以及用法再来学习Vue会事半功倍&#xff01; 一、初识Vue Vue.js&#xff08;读音 /vjuː/, 类似于 view&#xff09; 是一套构建用户界面的渐进式框架。Vue 只关注视图层&a…

【服务器数据恢复】raid5故障导致LUN无法访问的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器中有一组由数块SAS硬盘组建的RAID5阵列&#xff0c;阵列中有1块热备盘&#xff0c;上层部署OA以及Oracle数据库。 服务器故障&#xff1a; 该磁盘阵列中有2块硬盘出现故障先后离线&#xff0c;RAID5阵列瘫痪&#xff0c;上层LUN无法…

使用记事本编写第一个GO程序

开发环境&#xff1a; go1.18.3 记事本 先来看一下要编写的第一个hello,world Go程序 package main import "fmt"func main() {/* this is my first Go program*/fmt.Println("hello,world") } 第一行代码 package main定义了域名&#xff0c;你必须在源文…

设计模式->观察者设计模式和订阅者发布者设计模式的区别

设计模式->观察者设计模式和订阅者发布者设计模式的区别 一、先复习一下观察者设计模式的相关定义,优点,以及缺点1.定义观察者模式的三个典型例子 2.优点3.缺点4.观察者设计模式的主要角色5.代码举例完整代码 二、回答问题:观察者设计模式和订阅者发布者设计模式的区别 一、…

【Java-SpringBoot+Vue+MySql】项目开发综合—经验总结

目录 框架&#xff1a; 编程思维&#xff1a; MVC架构: 前端——组件式开发 开发思路梳理&#xff1a; 后端—— 前端—— 效果图 信息列表&#xff1a; 修改用户​编辑 新增用户 删除用户 数据清空 批量上传 框架&#xff1a; 后端&#xff1a;JAVA-SpringBoot2.6、包管理器M…

13.RocketMQ之消息的存储与发送

1. 消息存储 1.1 消息存储 分布式队列因为有高可靠性的要求&#xff0c;所以数据要进行持久化存储。 消息生成者发送消息Broker收到消息&#xff0c;将消息进行持久化&#xff0c;在存储中新增一条记录返回ACK给生产者Broker消息给对应的消费者&#xff0c;然后等待消费者返回A…

Keras-4-深度学习用于计算机视觉-猫狗数据集训练卷积网络

0. 说明&#xff1a; 本篇学习记录主要包括&#xff1a;《Python深度学习》的第5章&#xff08;深度学习用于计算机视觉&#xff09;的第2节&#xff08;在小型数据集上从头开始训练一个卷积神经网络&#xff09;内容。 相关知识点&#xff1a; 从头训练卷积网络&#xff1b…

AI 绘画用 Stable Diffusion 图生图局部重绘功能给美女换装(这是我能看的嘛)

昨天带大家一起装好了 Stable Diffusion 的环境&#xff0c;今天就来带大家一起体验一下 Stable Diffusion 的局部重绘功能。 没装好环境的可以看上一篇&#xff1a;AI 绘画基于 Kaggle 10 分钟搭建 Stable Diffusion&#xff08;保姆级教程&#xff09; Stable Diffusion 的…

可重入,可打断,公平锁,条件变量原理解读

目录 可重入原理 可打断原理 不可打断模式 可打断模式 公平锁实现原理 条件变量实现原理 await 流程 signal 流程 可重入原理 什么是可重入&#xff1a;当线程请求一个由其它线程持有的对象锁时&#xff0c;该线程会阻塞&#xff0c;而当线程请求由自己持有的对象锁…