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…

根据目标选择减肥方法 少做无用功

不同的美体目标适合的减肥方法也是不同的&#xff0c;有些人想减去大部分体重&#xff0c;而有些人只是想让身体曲线更柔美&#xff0c;这就要求有相应的减肥方法&#xff0c;对症下药&#xff0c;才会让减肥少做无用功。 目标&#xff1a;我想穿上小一码的衣服 建议&#x…

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

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

基于java的数据结构学习——动态数组C++类模板(含拷贝构造,重载常见运算符)

之前实现了java的动态数组&#xff0c;试着写了个C版的&#xff0c;同样对时间复杂度振荡进行了处理。纯手打&#xff0c;代码如下 &#xff1a; // // Created by PC-Saw on 2018/12/19. //#ifndef DATA_STRUCTURE_MYARRAY_H #define DATA_STRUCTURE_MYARRAY_H#include <i…

科目三考试过程详解

科目三是考驾照的最后一项考试&#xff0c;所以考生在这关都很注意&#xff0c;但是有可能是由于过于紧张都难免会有些失误&#xff0c;如果没过的话&#xff0c;那也就意味着您拿照的时间又延长了另外还要交补考费。因此很多学员都想一次性把这项考试通过&#xff0c;那么我们…

图解 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;虽然这并不花费很多代价。高质…

2014版学车考驾照精华攻略 总有一个你需要!赶紧收藏吧!!

新交规&#xff0c;新驾考&#xff0c;拿下本本&#xff0c;着实不容易。2013的你&#xff0c;是否已经踏上学车征程&#xff0c;为了顺利拿到本本而苦于八方搜索&#xff0c;四处奔波&#xff0c;一心只为获得有所帮助的经验之谈、简单易懂的学车攻略呢&#xff1f;本着锄强扶…

mybatis 逆向工程生成的 Example 类的使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一.逆向工程 逆向工程可以针对单表自动生成 mybatis 执行所需要的代码&#xff08;mapper.java,mapper.xml、po&#xff09;, 根据数据…

牛客假日团队赛8

牛客假日团队赛8 A Cell Phone Network 思路&#xff1a;最小支配集AC代码#include<stdio.h> #include<iostream> #include<math.h> #include<algorithm> #include<string.h> #include<queue> #include<set> #include<string>…

汽车标志大全 买车必知

简要介绍&#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.但是&…

Python与MySQL连接

import MySQLdb #注意大小写&#xff01;&#xff01;#建立和数据库系统的连接conn MySQLdb.connect(hostlocalhost,userroot,passwdsmile,dbtest)#获取操作游标cursor conn.cursor()#执行SQL,创建一个数据库.cursor.execute("""create database python"…

科目三靠边停车技巧要领

正在准备科目三的您&#xff0c;对顺利通过考试有信心吗&#xff1f;今天&#xff0c;小编为大家带来科目三靠边停车技巧&#xff0c;通过讲解靠边停车考试要求&#xff0c;让学员更好地掌握相关技巧&#xff0c;希望能帮到大家。 靠边停车考试项目中规定&#xff0c;车前保险杠…

解决: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…

dojo 九 effects dojo/_base/fx 和 dojo/fx

官方教程&#xff1a;Dojo Effects这里讲学习一下dojo如何实现淡入、淡出、滑动等效果。实现这些特殊的效果有两个包 dojo/_base/fx 和 dojo/fx。dojo/_base/fx 中提供了一些基础的animation方法&#xff0c;如&#xff1a; animateProperty, anim, fadeIn, and fadeOut.dojo/f…

电子路考容易犯错的五大细节

正在学车的你&#xff0c;知道在电子路考中哪些是考生常犯的错误吗&#xff1f;下面&#xff0c;小编为大家带来学车考生参加科目三考试特别容易犯错的地方&#xff0c;尤其是不按规定使用转向灯和在超车时不能根据道路交通情况合理选择行车道或速度这两项犯错的人最多。 ●起步…

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横向排列…

考驾照重点科目的关键考试技巧

定点停车停不好关键在于方向盘打得太晚&#xff0c;而且刹车没有控制好&#xff01;刹车和方向应该同步进行&#xff0c;方向盘不要打得太多。上坡停车或者3档以下停车可以先踩离合器&#xff0c;4-5档停车必须先刹车减速以后再踩离合器。 上坡定点停车步骤&#xff1a;听到指令…