算法刷题-数组

JZ4 二维数组中的查找

**题目描述:**在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

解决思路:

正常:双循环,挨个查找;【但是这种线性查找方法效率极低】

进阶:根据题面给出的条件(左到右递增,上到下递增),我们可以采取从右上角(或左下角)开始比较这样可以做到一次排除一行或者一列。

比如

1 2 3
2 3 4
4 5 6  //查找5
//右上角:是所在行的最大值,所在列的最小值
//3比5小 ==> 列++
//4比5小 ==> 列++
//6比5大 ==> 行--

在这个过程中要注意避免数组下标越界,所以循环的条件比较重要

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int row = array.size();//行
        int col = array[0].size();//列
        //array[i][j]
        int i = 0, j = col - 1;//用右上角的值来比较
        while(i < row && j >= 0)
        {
            //比右上角的值大,行++
            if(target > array[i][j]) i++;
            //比右上角的值小,列--
            else if(target < array[i][j]) j--;
            else if(target == array[i][j]) return true;
        }
        //走到这说明找不到
        return false;
    }
};

JZ11 旋转数组的最小数字

**题目描述:**有一个长度为 n 的非降序数组,比如[1,2,3,4,5],将它进行旋转,即把一个数组最开始的若干个元素搬到数组的末尾,变成一个旋转数组,比如变成了[3,4,5,1,2],或者[4,5,1,2,3]这样的。请问,给定这样一个旋转数组,求数组中的最小值。

解题思路

正常:1、遍历数组,找最小值【线性查找方法效率太低】;2、双指针,同时比较当前值和下一个值的大小。【时间复杂度与1一样,没有性能提升】

进阶:借鉴二分查找的思想,一个数组经过旋转后,得到的结果可以看作两个新的非降序数组,我们要做的就是找到两个新数组的分割位置,通过不断缩小[left, right]最终确定最小值!

left、right、mid三个下标,

  1 2 3 4 5//非降序数组
//情况1
  2    3    4    5    1
left       mid       right
此时a[left]<=a[mid],说明前半段是非降序数组;a[right]<a[mid],说明后半段顺序是不对的,那么对后半段再次进行查找
  2    3    4    5    1
          left  mid   right
此时a[left]<=a[mid],说明前半段是非降序数组;a[right]<a[mid],说明后半段顺序是不对的,那么对后半段再次进行查找
  2    3    4    5    1
             left/mid right
此时left==mid,说明right所指向的就是最小值

归纳:当a[left]<=a[mid]时,则要搜索后半段

//情况2
  5    1    2    3    4//旋转后
left       mid       right
此时a[left]>a[mid],说明前半段顺序是不对的;a[right]>a[mid],说明后半段是非降序数组,那么对前半段再次进行查找
  5    1    2    3    4//旋转后
left  mid   right
此时a[left]>a[mid],说明前半段顺序是不对的;a[right]>a[mid],说明后半段是非降序数组,那么对前半段再次进行查找
  5       1    2    3    4//旋转后
left/mid right
此时left==mid,说明right所指向的就是最小值

归纳:当a[left]>a[mid]时,则要搜索前半段

有一层隐含关系:当(left==mid) > (left+1right) ==> right指向的就是最小值。

非递减排序可能会出现a[left]==a[mid]==a[right]这种情况,我们就无法判定最小值在mid左侧还是右侧,就需要线性遍历了。

  1    1    1    0    1//旋转后
left       mid       right

总的循环条件是rotateArray[left] >= rotateArray[right](能进入循环的肯定是旋转数组!),在进入循环之前mid=0,这样可以保证遇到1 2 2 2(未旋转的数组)这种情况,仍可以判断出来

class Solution {
public:
    int minNumberInRotateArray(vector<int> rotateArray) {
        if(rotateArray.empty()) return 0;
        int left = 0;
        int right = rotateArray.size() - 1;
        int mid = 0;//如果这个数组是1 2 2 2没有旋转的数组,就是mid

        while(rotateArray[left] >= rotateArray[right])//保证该数组是旋转过的数组
        {
            if(right - left == 1)//两个下标相邻,右索引就是最小值
            {
                mid = right;
                break;
            }
            mid = (right + left) / 2;
            //如果无法判断大小,就线性遍历搜索最小值
            if(rotateArray[left] == rotateArray[mid] && rotateArray[right] == rotateArray[mid])
            {
                int min = rotateArray[left];
                for(int i = left + 1; i <= right; i++)
                {
                    if(rotateArray[i] < min)
                    {
                        min = rotateArray[i];                        
                    }
                }
                //遍历结束,返回最小值
                return min;
            }
            
            if(rotateArray[mid] >= rotateArray[left]) left = mid;//搜索后半段
            else right = mid;//搜索前半段
        }
        return rotateArray[mid];
    }
};

调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。如1 2 3 4 5 6

划重点:相对位置不变,得到1 3 5 2 4 6

解题思路

正常:1、改变相对位置。头尾双指针,头指针遇到奇数就++,遇到偶数停下来交换;尾指针遇到偶数就–,遇到奇数就停下来交换。2、不改变相对位置。new两个数组,遍历原数组,一个数组保存奇数,一个数组保存偶数,遍历结束,再把偶数数组的数据添加到奇数数组的后面。

进阶:借鉴插入排序的思想。从头开始遍历,遇到奇数就从当前位置开始从后向前覆盖式地挪动,直到上一个奇数处,留出了一个空位给当前奇数插入。覆盖式挪动,刚好把当前奇数覆盖掉,避免了数据冗余

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int k = 0;
        for(int i = 0; i < array.size(); i++)
        {
            if(array[i] & 1)//奇数
            {
                int tmp = array[i];//保存奇数,后续进行覆盖挪动
                int j = i;//从当前下标开始挪动,所以当前下标位置的数据会被覆盖
                while(j > k)
                {
                    array[j] = array[j-1];
                    j--;
                }
                array[k++] = tmp;
            }
        }
    }
};

JZ39 数组中出现次数超过一半的数字

题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

解题思路

思路一:定义map,使用<数字,次数>的映射关系,最后统计每个字符出现的次数。

思路二:排序,出现次数最多的数字,一定在中间位置。然后检测中间出现的数字出现的次数是否符合要求。

思路三:由于目标数据超过数组长度的一半这个前提条件,那么我们同时去掉两个不同的数字,到最后剩下的一个数就是该数字。如果剩下两个,那么这两个也是一样的,就是结果,在其基础上把最后剩下的一个数字或者两个,用原数组遍历,将数组遍历一遍统计一下数字出现次数进行最终判断。

采用消去法来解决,一个数据与另一个数据不同,则times=0表示已消去

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        if(numbers.size() == 0) return 0;

        int number = numbers[0];
        int times = 1;
        for(int i = 1; i < numbers.size(); i++)
        {
            if(times == 0)
            {
                number = numbers[i];
                times = 1;
                continue;
            }
            if(numbers[i] == number)
                times++;
            else times--;//两个数不同,则抵消
        }
        
        //后续还要再确认一下是否是这个数据
        int count = 0;
        for(int i = 0; i < numbers.size(); i++)
        {
            if(numbers[i] == number) count++;
        }

        return count > numbers.size()/2 ? number : 0;
    }
};

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

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

相关文章

iptables防火墙详解

文章目录一、iptables概念1、防火墙基础1.1 防火墙概念1.2 Netfilter和iptables的区别2、Iptables的表、链结构2.1 规则链2.2 规则表2.3 规则表之间的顺序3、规则3.1 匹配条件3.2 处理动作二、iptables规则管理1、iptables规则操作1.1 iptables信息查询1.2 规则添加1.3 规则删除…

Ant Design Vue的汉化

Ant Design Vue的汉化 1. 引入依赖 import zhCN from "ant-design-vue/lib/locale-provider/zh_CN"; // 汉化 export default {data () {zhCN,} }2. 标签包裹需要汉化的组件 <a-config-provider :locale"zhCN"><a-table :row-selection"ro…

C++IO流

文章目录一、CIO流体系二、C标准IO流三、C文件IO流1.ifstream2.ofstream一、CIO流体系 C流是指信息从外部输入设备向计算机内部输入&#xff0c;从内存向外部输出设备输出的过程&#xff0c;这种输入输出的过程非常形象地被称为流的概念。IO流指的就是输入输出流。 我们平时对…

PerfEnforce Demonstration: Data Analytics with Performance Guarantees

PerfEnforce Demonstration: Data Analytics with Performance Guarantees Created by: ctur Date: April 2, 2023 2:54 PM Status: ready to start 实时响应式的扩展算法 实时响应式的扩展算法分为 1. 比例积分控制 2. 强化学习 比例积分控制方法 “We use a proportiona…

现在的年轻人真会玩,开发界面都这么时尚,不服老都不行了

文章目录一、你还在用传统的开发界面吗二、年轻人的界面1.动漫型2.偶像型3.提神型三、更换背景的操作第一步第二步第三步一、你还在用传统的开发界面吗 不比不知道&#xff0c;一比吓一跳&#xff0c;都2023年了&#xff0c;你还在用Pycharm的默认背景写代码吗&#xff1f;已经…

不同版本的JDK新特性

1.JDK9&#xff1a;模块化开发 模块化功能用的不是很多 2.JDK10&#xff1a;var局部变量推导 使用var的两个基本要求&#xff1a; 也用得不是很多 3.JDK11 (1)单文件程序 就是能够直接用java命令编译.java文件了&#xff0c;跳过了使用javac命令的步骤&#xff0c;对新人…

4年功能测试月薪9.5K,3个月时间成功进阶自动化,跳槽涨薪6k后我的路还很长...

前言 其实最开始我并不是互联网从业者&#xff0c;是经历了一场六个月的培训才入的行&#xff0c;这个经历仿佛就是一个遮羞布&#xff0c;不能让任何人知道&#xff0c;就算有面试的时候被问到你是不是被培训的&#xff0c;我还是不能承认这段历史。我是为了生存&#xff0c;…

AD14安装步骤

首先 得需要科学安软件&#xff0c;我相信你可以找到的。 第一步&#xff1a;解压完成之后哦&#xff0c;双击打开AltiumDesignerSetup14_3_15.exe 第二步&#xff1a;点击next 第三步&#xff1a;先点击我同意&#xff0c;在点击next 第四步&#xff1a;点击next 第五步&…

路径 Dijkstra 蓝桥杯 JAVA

目录题目描述&#xff1a;Dijkstra 算法 (朴素版)&#xff1a;用Dijkstra解决本题&#xff1a;题目描述&#xff1a; 小蓝学习了最短路径之后特别高兴&#xff0c;他定义了一个特别的图&#xff0c;希望找到图中的最短路径。 小蓝的图由2021 个结点组成&#xff0c;依次编号1 至…

TypeScript由浅到深(上篇)

目录 一、什么是TypeScript有什么特点&#xff1a; 二、TypeScript的编译环境&#xff1a; 三、TypeScript数据类型&#xff1a; 01_标识符的类型推导&#xff1a; 02_JS中的类型Array&#xff1a; 03_JS 中的类型Object&#xff1a; 04_函数的类型&#xff1a; 05_匿名…

C++游戏分析与破解方法介绍

1、C游戏简介 目前手机游戏直接用C开发的已经不多&#xff0c;使用C开发的多是早期的基于cocos2dx的游戏&#xff0c;因此我们这里就以cocos2d-x为例讲解C游戏的分析与破解方法。 Cocos2d-x是一个移动端游戏开发框架&#xff0c;可以使用C或者lua进行开发&#xff0c;也可以混…

SpringBoot事件的选取原理

有四个事件启动监听器&#xff1a; 事件1会被监听吗&#xff1f;答案不会 容器发布一个正在启动的事件 org.springframework.context.event.AbstractApplicationEventMulticaster#retrieveApplicationListeners 遍历我们注册的监听器&#xff0c;但这里有个判断条件&#xff…

众人围剿,GPT-5招惹了谁

目录千人呼吁暂停AI训练代表人物分析反对原因分析信息安全人身安全失业利益总结GPT-4 火爆全球&#xff0c;引发了人工智能大浪潮。过去的一个月&#xff0c;OpenAI、微软、谷歌加上百度不断释放王炸&#xff0c;所有人都相信&#xff0c;AI 的就是未来的生产力。俗话说&#x…

Android动画进阶

在Android中&#xff0c;实现动画的方式通常有两种&#xff1a;视图动画和属性动画。然而这两种方式只能实现一些较为简单动画&#xff0c;仅仅通过改变这些控件属性的方式实现一些复杂的动画效果是比较有难度的&#xff0c;那么我们该如何实现复杂的动画。这里介绍两种实现方式…

Android配置Jetpack-Compose环境

Android 配置 Jetpack Compose 环境 记录配置Jetpack Compose环境的一些坑~ 本文同步更新于博客&#xff1a; 链接 直接创建kotlin项目或创建java项目后再配置均可 根目录 build.gradle 配置kotlin环境构建脚本 buildscript {ext.kotlin_version 1.4.32dependencies {clas…

大模型时代,AI模型开源还能这么玩?模型空间内测邀请(含重磅福利)

‍人工智能学习与实训社区飞桨 AI Studio自2019年以来&#xff0c;持续吸纳众多开发者于平台内开源贡献、实训提升&#xff0c;分享项目经验、共享自研模型等。 随着 AI Studio 开发者规模的增长、开发者开发能力的提升&#xff0c;我们收到许多期待与建议&#xff0c;经过一段…

企业OA管理系统需具备哪些功能?

OA也就是办公自动化&#xff0c;是通过将计算机、通信等现代化技术运用到传统办公方式而形成的一种新型办公方式。OA办公管理系统能够更加高效优质的处理办公事务以及进行企业管理业务&#xff0c;实现对资源的高效利用&#xff0c;进而达到提高生产力&#xff0c;提升管理水平…

详解vue各种权限控制与管理的实现思路

一、 菜单权限 菜单权限&#xff1a;控制用户在系统中能够看到哪些菜单项菜单权限指的就是后台系统中的左侧的菜单栏&#xff0c;前端可以根据后端接口返回的权限数据结合element-ui菜单组件循环拼接而成即可&#xff0c;有什么权限就展示什么菜单通过vuex持久化插件(本地存储…

Linux系统【centos7】常用基础命令教程

今天我来介绍一下Linux系统的基础知识。 首先&#xff0c;我们需要了解Linux是什么。Linux是一种免费且开放源代码的操作系统&#xff0c;它被广泛用于服务器、移动设备和嵌入式系统。 接下来&#xff0c;我们需要了解基本的Linux命令。其中一些基本命令包括&#xff1a; 1.…

项目 TO 的自我修养

最近作为项目 TO 在公司内完成了一个涉及面比较广的项目&#xff0c;对于如何推动项目上线有一些经验和大家分享。希望刚毕业几年、没有参与过大型项目的同学&#xff0c;从中能学到一些方法&#xff0c;为今后担任项目主力做一些准备。所谓的 TO&#xff0c;是 Technical Owne…
最新文章