1 两数之和

虽然只是一道很简单的题,但是也给我很多思考。

刚看到这道题的时候没有仔细思考,直接写了个排序和二分查找,想着对每个数字查找另一个数字会不会出现,复杂度是O(nlogn+nlogn)O(nlogn+nlogn)O(nlogn+nlogn),主要训练了一下自己手写快速排序和二分查找。

class Solution {void swap(vector<int>& a,vector<int>& b,int i,int j){int t=a[i]; a[i]=a[j]; a[j]=t;t=b[i]; b[i]=b[j]; b[j]=t;}void getPovit(vector<int>& a, vector<int>& b,int l,int r){//三者取中得到枢纽int mid = (l+r) >> 1;if(a[l] < a[mid]) swap(a, b, l, mid);if(a[r-1] < a[mid]) swap(a, b, r-1, mid);if(a[l] > a[r-1]) swap(a, b, l, r-1);}void quickSort(vector<int>& a,vector<int>& b, int l,int r){if(r-l < 2) return;int mid = (l+r) >> 1;getPovit(a, b, l, r);int povit = a[l];int i=l-1; int j=r;while(i<j){do ++i; while(a[i] < povit);do --j; while(a[j] > povit);if(i < j) swap(a, b, i, j);}quickSort(a, b, l, j+1);quickSort(a, b, j+1, r);}int bSearch(vector<int>& a, int l,int r,int x,int now){if(r<=l) return -1;int mid = (l+r) >> 1;if( a[mid] == x && mid != now) return mid;if(a[mid] < x) return bSearch(a, mid+1, r, x, now);else return bSearch(a, l, mid, x, now);}
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> b;int n = nums.size();for(int i=0; i<n; ++i){b.push_back(i);}quickSort(nums, b, 0, n);// sort(nums.begin(), nums.end());vector<int> ret;for(int i=0; i<n; ++i){int tmp = target - nums[i];int j = bSearch(nums, 0, n, tmp, i);if(-1 != j){ret.push_back(b[i]); ret.push_back(b[j]);break;}}return ret;}
};

上面的做法很傻,稍微聪明一点的做法是排序以后从两边开始查找。这样的复杂度是O(nlogn+n)O(nlogn+n)O(nlogn+n)的。因为我们求的是两个数字的和,所以对于一个排好序的数组来讲,如果一个数字增大,另一个数字一定减小。因此我们用两个指针,一个指向数组的头部,一个指向数组的尾部,如果出现所求的和就直接返回答案,如果两个指针和比目标小就将前一个指针后移,如果比目标大就把后一个指针前移。这种直觉很容易证明是正确的。

class Solution {void swap(vector<int>& a,vector<int>& b,int i,int j){int t=a[i]; a[i]=a[j]; a[j]=t;t=b[i]; b[i]=b[j]; b[j]=t;}void getPovit(vector<int>& a, vector<int>& b,int l,int r){//三者取中得到枢纽int mid = (l+r) >> 1;if(a[l] < a[mid]) swap(a, b, l, mid);if(a[r-1] < a[mid]) swap(a, b, r-1, mid);if(a[l] > a[r-1]) swap(a, b, l, r-1);}void quickSort(vector<int>& a,vector<int>& b, int l,int r){if(r-l < 2) return;int mid = (l+r) >> 1;getPovit(a, b, l, r);int povit = a[l];int i=l-1; int j=r;while(i<j){do ++i; while(a[i] < povit);do --j; while(a[j] > povit);if(i < j) swap(a, b, i, j);}quickSort(a, b, l, j+1);quickSort(a, b, j+1, r);}int bSearch(vector<int>& a, int l,int r,int x,int now){if(r<=l) return -1;int mid = (l+r) >> 1;if( a[mid] == x && mid != now) return mid;if(a[mid] < x) return bSearch(a, mid+1, r, x, now);else return bSearch(a, l, mid, x, now);}
public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> b;int n = nums.size();for(int i=0; i<n; ++i){b.push_back(i);}quickSort(nums, b, 0, n);// sort(nums.begin(), nums.end());int i = 0, j = n-1;while(i < j){if(nums[i] + nums[j] == target)return vector<int>{b[i], b[j]};if(nums[i] + nums[j] < target)++i;else --j; }return vector<int>();}
};

官方给出的题解是通过使用HashMap解决的,发现这样的效率很好,然而我之前没有接触过HashMap,通过一番学习,用HashMap解决了一下。

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

但是也没有觉得快多少,可能是因为数据比较水看不出来差距吧。

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

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

相关文章

834 树中距离之和

这道题我自己的想法只有对每个点都用一遍Dijkstra然后再求和&#xff0c;显然会超时&#xff0c;所以我都没有尝试。 研究了一下题解&#xff0c;发现题解很巧妙&#xff0c;自己对树的处理还是太稚嫩&#xff0c;之前树链剖分学的都忘光了。 对于固定根节点的&#xff0c;我…

75 颜色分类

题目已经提示可以一遍扫描了但是我还是没有想到&#xff0c;其实双指针的想法我已经有了&#xff0c;但是一想到有问题就觉得无法实现。这也揭示了我思维上的问题&#xff1a;用一种方法解决问题遇到困难第一件事情不是想着如何攻克而是想着换一种方法。对自己的思维也不自信。…

141 环形链表

要求使用空间复杂度为O(1)的方法&#xff0c;可是我并没有想到。我想到的只有用一个哈希表记录一下所有访问过的节点。 题解给出的空间复杂度为O(1)的方法是使用两个指针&#xff0c;然后让一个一次跑一步&#xff0c;一个一次跑两步&#xff0c;如果跑的快的能追上跑的慢的就…

数据可视化【十五】

经验法则&#xff1a;在颜色不相邻的时候加上背景颜色颜色的个数为6~12比较好。 颜色其实很大程度上由背景决定而不是他本身决定。 D3 Scale-Chromatic 有许多颜色刻度&#xff0c;可以根据自己的需要进行选择。 参考论文&#xff1a;Practical Rules for Using Color in Cha…

Ubuntu修改/删除主目录下的中文文件夹

在Ubuntu的主目录下一般是有一些中文的目录&#xff0c;例如桌面&#xff0c;视频等等&#xff0c;还无法修改名称&#xff0c;在一群英文文件夹里面显得有些突兀&#xff08;Ubuntu终端下的中文一点也不好看&#xff09;&#xff0c;就想把这些文件夹修改一下&#xff0c;结果…

19 删除链表的倒数第N个

题目的意思很简单&#xff0c;就是删除一个链表倒数第N个节点。 需要用到链表的标准操作&#xff1a;快慢指针。 我们让一个快指针先指向第N个元素&#xff0c;这个时候快指针总比慢指针领先N个元素&#xff0c;等到快指针指向链表尾部的时候慢指针就指向需要删除的元素。 之前…

844. Backspace String Compare

题目的意思大概是有两个字符串&#xff0c;其中的#表示退格键&#xff0c;让比较最后两个字符串是否相当。 很容易想到的思路就是用一个栈进行模拟这个过程&#xff0c;特别需要注意如果一个串是空串也是可以退格的。 但是很容易想到的另一个特性就是&#xff0c;前面的字符有…

链表三连击

876&#xff1a;链表的中间节点 206&#xff1a;反转链表 143&#xff1a;重排练表 链表的中间节点 这个题一看就是最简单的快慢指针&#xff0c;但是在具体实现的时候我还是犹豫思考了一下&#xff1a;要不要在链表前面放置哑节点&#xff0c;快指针应该什么时候判断已经到达…

D3力导引图

学习力导引图的时候在网上没有找到什么好的教程&#xff0c;支离破碎地进行了一段时间的学习&#xff0c;还阅读了d3的关于d3的官方文档&#xff0c;但是始终觉得不的要领。这里记录一下我学习力导引图的一些心得以及推荐一下学习资源。 学习资源 官方文档&#xff1a;https:…

Ubuntu Pycharm启动后卡住无法操作

昨天还好好的&#xff0c;今天打开Pycham突然卡住了&#xff0c;卡在了那个preparing workspace的地方&#xff0c;然后在网上搜索了很多方法都没用。直到在网上看到有个大佬说是因为搜狗输入法的问题&#xff0c;我才突然记起来昨天安装了搜狗输入法。。。 kill掉卡住的Pycha…

327 区间和的个数

题目描述 Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive. Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive. Note: A naive algorithm of O(n2) is t…

浏览器访问本地文件

之前一直苦恼无法在浏览器访问本地文件&#xff0c;尤其是写的网页需要调用外部数据的时候&#xff0c;今天学习到可以用python很方便的解决问题 如果有python3环境&#xff0c;直接在对应的文件夹下运行&#xff08;这里是Ubuntu环境&#xff0c;如果是Windows应该在命令行也…

Ubuntu使用jupyter notebook +导出PDF

因为最近需要做数据分析的工作&#xff0c;所以复习了一下numpy和pandas&#xff0c;并安装了jupyter notebook进行数据分析&#xff0c;这里记录一下环境的设置。 ps:jupyter notebook真香 安装 python3 -m pip install --upgrade pip //升级pip pip3 install jupyter使用 …

SSH:WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

给服务器重装了一下系统&#xff0c;结果报了上述错误&#xff1a; WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! ...在网上找…

Ubuntu20.04 更新后黑屏无法加载驱动

本来我的电脑好好的&#xff0c;突然提示说有可应用的更新&#xff0c;我想都没想就直接更新了&#xff0c;可是没想到更新以后经过grub以后就会黑屏&#xff0c;一动不动&#xff0c;在网上搜索了许多&#xff0c;提到的说法是在grub界面对第一个Ubuntu的启动按e进行编辑 在倒…

每日一题:leetcode1489. 找到最小生成树里的关键边和伪关键边

时隔多年我终于又开始写博客了&#xff0c;主要是已经放假了&#xff0c;之前一直忙于考试和课设没有时间写博客&#xff0c;学习笔记也因为买了iPad的缘故大部分都是手写的了。 假期想要把以前做过的项目都整理一下放在github和CSDN上。 也已经很久没有写算法题了&#xff0…

每日一题:leetcode989.数组形式的整数加法

题目描述 题目分析 题目非常简单&#xff0c;但是我还是wa了几发&#xff0c;对不起&#xff0c;我太菜了。我的想法是把K转换为数组然后用大整数加法处理。但是因为太久没有写了导致写了好久。 class Solution { public:void add(vector<int> &A, vector<int&g…

每日一题:leetcode674.最长连续递增序列

题目描述 题目分析 一遍遍历&#xff0c;如果硬要说用了什么算法的话觉得应该算是一个简单的滑动窗口吧 AC代码 class Solution { public:int findLengthOfLCIS(vector<int>& nums) {if (nums.size() 0) {return 0;}int ret 1;int cnt 1;for (int i 1; i <…

每日一题:leetcode959.由斜杠划分区域

题目描述 题目分析 仔细分析这道题以后虽然觉得可能要转化为图之类的&#xff0c;但是完全没有具体的想法&#xff0c;因为每个格子都有三种情况&#xff0c;这三种情况的不同的组合又会产生不同的结果。 发现找不到编码转化为图以后&#xff0c;我分析了一下不同数量方块之间…

每日一题:leetcode1319.联通网络的操作次数

题目描述 题目分析 ps&#xff1a;这篇博客是补前天的&#xff0c;前天在老家不方便写博客 题目挺简单的&#xff0c;但是通过题目对图的连通性有了一个更深刻的认识&#xff1a;如果有超过&#xff08;或等于&#xff09;n-1条边&#xff0c;则一定是可以让整个图联通的。 如…