leetcode练习——数组篇(1)(std::ios::sync_with_stdio(false);std::cin.tie(nullptr);)

题号1. 两数之和:

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

你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

才拿到这道题时,第一个反应是遍历每个元素 x,并查找是否存在一个值与 target−x 相等的目标元素的暴力解法,时间复杂度为O(n²),C++实现如下:

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> ret;for (int i = 0; i < nums.size(); i++){for(int j = i + 1; j < nums.size(); j++){if(nums[i] == target - nums[j]){ret.push_back(i);ret.push_back(j);return ret;}                }}ret.push_back(-1);ret.push_back(-1);return ret;}
};

 

系统耗时显示是164ms, 对于每个元素,我们试图通过遍历数组的其余部分来寻找它所对应的目标元素,这将耗费 O(n) 的时间。因此时间复杂度为 O(n^2),空间复杂度为O(1)。

 

为了对运行时间复杂度进行优化,我们需要一种更有效的方法来检查数组中是否存在目标元素。如果存在,我们需要找出它的索引。保持数组中的每个元素与其索引相互对应的最好方法是什么?哈希表。

class Solution {
public:vector<int> twoSum(vector<int>& nums, int target){unordered_map<int, int> hm1;for (int i = 0; i < nums.size(); ++i) {int complement = target - nums[i];if(hm1.find(complement) != hm1.end()){return vector<int>{hm1.find(complement)->second, i};}hm1[nums[i]] = i;}return vector<int>{-1, -1};}
};

时间立马缩减到了8ms,性能的提升是立竿见影的,但是看了标准答案,看到有位大神居然将耗时缩减到了4ms,这里附上他的解法:

static const auto io_sync_off = []()
{// turn off syncstd::ios::sync_with_stdio(false);// untie in/out streamsstd::cin.tie(nullptr);return nullptr;
}();class Solution {
public:vector<int> twoSum(vector<int>& nums, int target){map<int, int> hm1;for (int i = 0; i < nums.size(); ++i) {int complement = target - nums[i];if(hm1.find(complement) != hm1.end()){return vector<int>{hm1.find(complement)->second, i};}hm1[nums[i]] = i;}return vector<int>{-1, -1};}
};

看完特地查了下开头的函数,详细的解释在下面:https://blog.csdn.net/qq_32320399/article/details/81518476

https://blog.csdn.net/YinJianxiang/article/details/76436089

在ACM里,经常出现数据集超大造成 cin TLE的情况。这时候大部分人(包括原来我也是)认为这是cin的效率不及scanf的错,甚至还上升到C语言和C++语言的执行效率层面的无聊争论。其实像上文所说,这只是C++为了兼容而采取的保守措施。我们可以在IO之前将stdio解除绑定,这样做了之后要注意不要同时混用cout和printf之类

在默认的情况下cin绑定的是cout,每次执行 << 操作符的时候都要调用flush,这样会增加IO负担。可以通过tie(0)(0表示NULL)来解除cin与cout的绑定,进一步加快执行效率。


题号4. 寻找两个有序数组的中位数:

给定两个大小为 m 和 n 的有序数组 nums1 和 nums2

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 nums1 和 nums2 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]则中位数是 (2 + 3)/2 = 2.5

我的思路是类似二路归并排序,但是不需要新的数组来存放两个数组的数据,也不需要将所有数据全部排序,只需要取到中间两个数。首先计算出总个数,然后求出中间两个数的下标 m 和 n ,定义两个指针,分别从两个数组的左边开始向后推进,知道遍历到第 m 个和第 n 个,求出两数的平均数并返回。当然这里同样解除了 IO 的同步用于提升性能。

double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{int size = nums1.size() + nums2.size();int m = 0, n = 0;// 判断中位数是两数平均值还是单个值if (size % 2 == 1) // 总个数为基数则为中间值{n = size / 2;m = n;}else                // 偶数则为中间俩个数的平均值{n = size / 2;m = n - 1;}double midData = 0;int leftPoint  = 0;int rightPoint = 0;// 获取中位数for (int i = 0; i <= n; ++i){// 对数组进行判断是否越界if ( leftPoint >= nums1.size() ) // 即将进行的操作下标将越界{if (midData == 0)midData = ( (double)( nums2[m - leftPoint] + nums2[n - leftPoint] ) ) / 2;elsemidData = ( midData + nums2[n - leftPoint] ) / 2;return midData;}if ( rightPoint >= nums2.size() ) // 即将进行的操作下标将越界{if (midData == 0)midData = ( (double)( nums1[m - rightPoint] + nums1[n - rightPoint] ) ) / 2;elsemidData = ( midData + nums1[n - rightPoint] ) / 2;return midData;}// 向后推进if (nums1[leftPoint] <= nums2[rightPoint]){if (i == m)midData = (double)nums1[leftPoint];if (i == n){midData = ( midData + nums1[leftPoint] ) / 2;return midData;}leftPoint++;} else{if (i == m)midData = (double)nums2[rightPoint];if (i == n){midData = ( midData + nums2[rightPoint] ) / 2;return midData;}rightPoint++;}}return midData;
}

这里出现了一个很奇怪的事情,我的方法在leetcode上显示的时间耗时是32ms,我采用16ms的方法,提交之后还是显示的32ms,于是我在自己电脑上写了测试用例计算耗时:

#include <iostream>
#include <windows.h>
#include <vector>
#include <unordered_map>using namespace std;// 关闭 IO 同步
static const auto io_sync_off = []()
{// turn off syncstd::ios::sync_with_stdio(false);// untie in/out streamsstd::cin.tie(nullptr);return nullptr;
}();double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2)
{int size = 0;if(nums1.size() != 0 || nums2.size() != 0){size = nums1.size() + nums2.size();}else{return false;}int m = 0, n = 0;// 判断中位数是两数平均值还是单个值if (size % 2 == 1) // 总个数为基数则为中间值{n = size / 2;m = n;}else                // 偶数则为中间俩个数的平均值{n = size / 2;m = n - 1;}double midData = 0;int leftPoint  = 0;int rightPoint = 0;// 获取中位数for (int i = 0; i <= n; ++i){// 对数组进行判断是否越界if ( leftPoint >= nums1.size() ) // 即将进行的操作下标将越界{if (midData == 0)midData = ( (double)( nums2[m - leftPoint] + nums2[n - leftPoint] ) ) / 2;elsemidData = ( midData + nums2[n - leftPoint] ) / 2;return midData;}if ( rightPoint >= nums2.size() ) // 即将进行的操作下标将越界{if (midData == 0)midData = ( (double)( nums1[m - rightPoint] + nums1[n - rightPoint] ) ) / 2;elsemidData = ( midData + nums1[n - rightPoint] ) / 2;return midData;}// 向后推进if (nums1[leftPoint] <= nums2[rightPoint]){if (i == m)midData = (double)nums1[leftPoint];if (i == n){midData = ( midData + nums1[leftPoint] ) / 2;return midData;}leftPoint++;} else{if (i == m)midData = (double)nums2[rightPoint];if (i == n){midData = ( midData + nums2[rightPoint] ) / 2;return midData;}rightPoint++;}}return midData;
}// 性能最优解法
int findKth(vector<int> nums1, vector<int> nums2, int k) 
{if (nums1.empty()) return nums2[k - 1];if (nums2.empty()) return nums1[k - 1];if (k == 1) return min(nums1[0], nums2[0]);int i = min((int)nums1.size(), k / 2), j = min((int)nums2.size(), k / 2);if (nums1[i - 1] > nums2[j - 1]) {return findKth(nums1, vector<int>(nums2.begin() + j, nums2.end()), k - j);} else {return findKth(vector<int>(nums1.begin() + i, nums1.end()), nums2, k - i);}return 0;
}double findMedianSortedArrays2(vector<int>& nums1, vector<int>& nums2) 
{int m = nums1.size(), n = nums2.size();return (findKth(nums1, nums2, (m + n + 1) / 2) + findKth(nums1, nums2, (m + n + 2) / 2)) / 2.0;
}int main() 
{struct timespec startTime,endTime;// 题号 4 测试用例
#if 1clock_gettime(CLOCK_MONOTONIC, &startTime);vector<int> vector1;vector<int> vector2;vector1.push_back(1);vector1.push_back(2);vector2.push_back(4);vector2.push_back(6);clock_gettime(CLOCK_MONOTONIC, &endTime);cout << "pushIn vector time cost :" << endTime.tv_nsec - startTime.tv_nsec << " ns" << endl;// my methodclock_gettime(CLOCK_MONOTONIC, &startTime);for (int i = 0; i < 10; ++i)findMedianSortedArrays(vector1,vector2);clock_gettime(CLOCK_MONOTONIC, &endTime);cout << "my   function time cost :" << endTime.tv_nsec - startTime.tv_nsec << "ns" << endl;// 最佳方法clock_gettime(CLOCK_MONOTONIC, &startTime);for (int i = 0; i < 10; ++i)findMedianSortedArrays2(vector1,vector2);clock_gettime(CLOCK_MONOTONIC, &endTime);cout << "best function time cost :" << endTime.tv_nsec - startTime.tv_nsec << "ns" << endl;
#endifreturn 0;  
}

我的电脑上函数运行10次耗时如图所示。

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

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

相关文章

intellij idea 中去除 @Autowired 注入对象带来的红色下划线报错提示

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 PS&#xff1a; 有 2 种方法&#xff0c;第 2 种方法更简单&#xff0c;在此谢谢好心友人的评论。 方法1&#xff1a; idea中通过Autow…

Coolite动态加载CheckboxGroup,无法在后台中获取

Coolite在后台动态加载CheckboxGroup&#xff0c;页面显示都正常&#xff0c;但是在后台去获取选中的checkbox时&#xff0c;使用下方法&#xff1a; ///<summary>///获取所选权限 ///</summary>///<returns></returns>privatestringGetPermiss…

图解 IDEA 中 springboot 项目 MyBatis Generator 逆向生成实体类及 mapper 配置文件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一、准备工作&#xff1a; 1. 新建一个 配置文件&#xff1a;generatorConfig.xml 。 <?xml version"1.0" encoding&qu…

关于IIS 7.5 限制连接数与流量限制模块

网页中的视频是用户喜闻乐见的常见形式之一&#xff0c;并在主要的站点中中以某种形式&#xff08;产品视频、教程视频、理财场景、user generated content、消费报告等&#xff09;在更广泛的应用。 其中的一个挑战是把视频加入到站点&#xff0c;虽然这并不花费很多代价。高质…

汽车标志大全 买车必知

简要介绍&#xff1a;为您提供汽车标志、世界汽车标志大全、各种汽车标志、国产汽车标志大全、汽车标志图片、汽车标志及名称、名车标志大全、世界名车排行榜、世界十大名车、世界名车图片等有关汽车标志、汽车图片、汽车名字及汽车品牌方面的知识。 欧美汽车标志图片大全_欧美…

解决: Caused by: java.lang.IllegalStateException: Cannot load driver class: com.mysql.jdbc.Driver

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 报错&#xff1a; Caused by: java.lang.IllegalStateException: Cannot load driver class: com.mysql.jdbc.Driver 2.但是&…

解决:Field xxMapper in xx.service.impl.xxServiceImpl required a bean of type ‘xx.mapper.xxMapper‘

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 启动 springboot 项目报错&#xff1a; Field userMapper in gentle.service.impl.UserServiceImpl required a bean of type gent…

Linux 查看 MySQL 版本的四种方法

1 在终端下执行 mysql -V 2 在help中查找 mysql --help |grep Distrib 3 在mysql 里查看 select version() 4 在mysql 里查看 status 转自&#xff1a;https://blog.csdn.net/chengyuc/article/details/77094775

html 基本布局介绍

1、div默认是纵向排列的&#xff0c;例子如下&#xff1a; <div id"wrap"><div id"div1">div1</div><div id"div2">div2</div><div id"div3">div3</div> </div> 2、如果要div横向排列…

@JsonSerialize 使用:注解方式 实现条件判断属性值、条件修改属性值

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 数据库中是 1、0 记录性别。 预期效果为&#xff1a;当查到属性值为 1 时&#xff0c;就给序列化后的 json 中性别字段赋值为 “男”…

【Android开发】NDK开发(1)-Hello World!

上半年&#xff0c;公司的一个项目&#xff0c;本身我是不喜欢Android开发的&#xff0c;但是学习到的东西总需要整理一下。 从iOS转到Android&#xff0c;真心有些不习惯。就IDE来说&#xff0c;eclipse比Xcode差的不是一点半点。Android模拟器竟然还要开机&#xff01;我勒个…

jQuery 实现表格与 ckeckbox 的全选、单选功能

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 功能点 1. 用户点击头的checkbox时&#xff0c;所有表格数据行的checkbox全选或反选。 当数据行某一行没有选中时&#xff0c;头check…

VUE:checkbox 单选框(单选、多选)、一选全选 / 全选一选、表格单选列实现

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 效果&#xff1a;如红框中部分。 一选全选&#xff1a;表头上的单选框选中则下面每行都选中。 全选一选&#xff1a;表中数据每行都…

我爱学习第一天(委托)

---恢复内容开始--- 1.delegate 一般用法 delegate void WriteValue(string vale);//申明一个委托,参数是string类型,无返回值static void Main(string[] args){WriteValue write new WriteValue(WriteLine);//实例化委托write("喝水");//调用Console.ReadKey();}pu…

VUE:父子组件间传参、子组件传值给父组件、父组件传值给子组件

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Vue是一个轻量级的渐进式框架&#xff0c;对于它的一些特性和优点在此就不做赘述&#xff0c;本篇文章主要来探讨一下Vue子父组件通信的…

c1科目三考试技巧

起步平稳。转向灯不要错了。靠边要和路边平行。离边近量保持&#xff1a;30CM距离。车子在运行中。换档尽量保持利落。若道路比较复杂。看好路牌路标&#xff0c;不要违规。一般很容易过的。你不要紧张。晚上夜考灯光把好。一切很顺利的。祝你好运。 方法/步骤 紧记着“一灯二…

Astyle 一键格式化项目代码

代码格式化差异问题&#xff1a; 一个团队有多个开发&#xff0c;因开发习惯不同&#xff0c;开发时少添加了空格、换行等。 格式化代码时&#xff0c;一般会将整个文档格式化&#xff0c;代码提交时会发现未知的修改项。 Astyle格式化工具 官网下载地址&#xff1a;Artistic S…

浅谈 JavaScript、ECMAScript (ES5、ES6)是什么、相互关系

一、ECMAScript 和 JavaScript 的关系 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 ES6 ECMAScript6 从百度百科的资料上来看&#xff1a; ECMAScript是一种由Ecma国际通过ECMA-…

CorelDRAW X7 X8 2017 2018是什么关系?

从CorelDRAW 2017版本开始我们叫习惯了的X几系列的CorelDRAW毅然决然的就换了称呼&#xff0c;所以有时候很多朋友对于软件版本&#xff0c;经常会傻傻分不清&#xff0c;还有人认为X8版本比2017版本高&#xff0c;究竟为什么会这么认为呢&#xff1f; “帮我转个X8吧”。 “我…

阮一峰 《ECMAScript 6 入门》:let 和 const 命令

以下内容全文出自 阮一峰的书&#xff1a; 《ECMAScript 6 入门》 电子版地址&#xff1a;ES 6标准入门&#xff08;第3版&#xff09; let 命令 基本用法 ES6 新增了let命令&#xff0c;用来声明变量。它的用法类似于var&#xff0c;但是所声明的变量&#xff0c;只在let命令…