两数之和 (简单)
题目描述
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数; 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
例如: 给定 nums = [2,7,11,15] ,target = 9 因为 nums[0] + nums[1] = 9; 因此返回 [0,1];
v1.0代码如下: 正数、0或重复值通过测试; 异常用例: [-1, -2, -3, -4, -5] -8; 输出 []
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var twoSum = function(nums, target) {
var tmp = target;
var result = [];
for(i=0; i < nums.length; i++){
if(nums[i] <= tmp){
tmp = target - nums[i];
var last = nums.length - i - 1;
for(j=0; j < nums.length; j++){
if(nums[j] === tmp && j != i){
result.push(i,j);
return result;
}
}
}
}
return result;
};
分析: 首先想到使用减法得到另一个数,因此考虑过滤掉所有小于target的值;但未考虑负数的情况。 解决方案,去掉外循环的if判断
官方解析:
上述方案属于暴力解法,遍历每个元素并查找是否有一个值与target-x相等的元素。 时间复杂度 O(n2);空间复杂度 O(1);
方法2 两遍哈希表
为了优化时间复杂度,需要更有效的方法来检查数组中是否存在目标元素。如果存在,需要知道其索引。保持数组中每个元素与其索引相互对应的最好方法是哈希表。
通过以空间换取速度的方式,我们可以将查找时间从 O(n)降低到 O(1)。哈希表正是为此目的而构建的,它支持以 近似 恒定的时间进行快速查找。我用“近似”来描述,是因为一旦出现冲突,查找用时可能会退化到 O(n)。但只要你仔细地挑选哈希函数,在哈希表中进行查找的用时应当被摊销为 O(1)。
算法思路: 使用两次迭代。在第一次迭代中,将每个元素的值和其索引添加到表中,在第二次迭代中,检查每个元素所对应的目标元素(target - nums[i])是否存在于表中。同时注意该元素不能是该元素本身。
Code:
/**
* 在js中没有hashTable,但是js的Object属性是基于
* hashTable实现的,因此可以有:
* var person = {};
* person[‘name‘] = "Test"
* 因此,利用该特性,封装hashTable的函数即可使用
**/
var twoSum = function(nums, target){
var result = [];
for(i=0; i < nums.length; i++>){
map.add(nums[i], i);
}
for(i=0; i < nums.length; i++){
var tmp = target - nums[i];
if(map.containsKey(tmp) && map.getValue(tmp) != i){
result.push(i);
result.push(map.getValue(tmp));
}
}
}
var map = new HashTable();
var HashTable = function(){
// HashTable 一般操作包括:
// add(k, v); getValue(k); remove(k);
// containsValue(v); containsKey(k);
// getValues(); getSize(); getKeys();
// Clear();
var size = 0;
var entry = new Object();
this.add = function(k, v){
if(!this.containsKey(k)){
size++;
entry[k] = v;
}
}
this.getValue = function(k){
return this.containsKey(k) ? entry[k] : null;
}
this.remove = function(k){
if(this.containsKey(k) && delete entry[k]{
size--;
}
}
this.containsKey = function(k){
return (k in entry);
}
this.containsValue = function(v){
for (var prop in entry){
if(entry[prop] == value){
return true;
}
}
return false;
}
this.getValues = function(){
var values = new Array();
for(var prop in entry){
values.push(entry[prop]);
}
return values;
}
this.getKeys = function(){
var keys = new Array();
for(var prop in entry){
keys.push(prop);
}
return keys;
}
this.getSize = function(){
return size;
}
this.clear = function(){
size = 0;
entry = new Object();
}
}
在上述方法中,时间复杂度为O(n);哈希表的引入使得查找元素的时间缩短到O(1); 空间复杂度为 O(n);
代码为js编写,因此在方案2中需要自行实现一个Hash Table
body { font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback"; font-size: 14px; padding: 0 12px; line-height: 22px }
#code-csp-warning { position: fixed; top: 0; right: 0; color: white; margin: 16px; text-align: center; font-size: 12px; font-family: sans-serif; background-color: #444444; cursor: pointer; padding: 6px }
#code-csp-warning:hover { text-decoration: none; background-color: #007acc }
body.scrollBeyondLastLine { margin-bottom: calc(100vh - 22px) }
body.showEditorSelection .code-line { position: relative }
body.showEditorSelection .code-active-line::before,body.showEditorSelection .code-line:hover::before { content: ""; display: block; position: absolute; top: 0; left: -12px; height: 100% }
body.showEditorSelection li.code-active-line::before,body.showEditorSelection li.code-line:hover::before { left: -30px }
.vscode-light.showEditorSelection .code-active-line::before { border-left: 3px solid rgba(0, 0, 0, 0.15) }
.vscode-light.showEditorSelection .code-line:hover::before { border-left: 3px solid rgba(0, 0, 0, 0.40) }
.vscode-dark.showEditorSelection .code-active-line::before { border-left: 3px solid rgba(255, 255, 255, 0.4) }
.vscode-dark.showEditorSelection .code-line:hover::before { border-left: 3px solid rgba(255, 255, 255, 0.60) }
.vscode-high-contrast.showEditorSelection .code-active-line::before { border-left: 3px solid rgba(255, 160, 0, 0.7) }
.vscode-high-contrast.showEditorSelection .code-line:hover::before { border-left: 3px solid rgba(255, 160, 0, 1) }
img { max-width: 100%; max-height: 100% }
a { color: #4080D0; text-decoration: none }
a:focus,input:focus,select:focus,textarea:focus { outline: 1px solid -webkit-focus-ring-color }
hr { border: 0; height: 2px; border-bottom: 2px solid }
h1 { padding-bottom: 0.3em; line-height: 1.2; border-bottom-width: 1px; border-bottom-style: solid }
h1,h2,h3 { font-weight: normal }
h1 code,h2 code,h3 code,h4 code,h5 code,h6 code { font-size: inherit; line-height: auto }
a:hover { color: #4080D0; text-decoration: underline }
table { border-collapse: collapse }
table>thead>tr>th { text-align: left; border-bottom: 1px solid }
table>thead>tr>th,table>thead>tr>td,table>tbody>tr>th,table>tbody>tr>td { padding: 5px 10px }
table>tbody>tr+tr>td { border-top: 1px solid }
blockquote { margin: 0 7px 0 5px; padding: 0 16px 0 10px; border-left: 5px solid }
code { font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback"; font-size: 14px; line-height: 19px }
body.wordWrap pre { white-space: pre-wrap }
.mac code { font-size: 12px; line-height: 18px }
pre:not(.hljs),pre.hljs code>div { padding: 16px; overflow: auto }
.vscode-light,.vscode-light pre code { color: rgb(30, 30, 30) }
.vscode-dark,.vscode-dark pre code { color: #DDD }
.vscode-high-contrast,.vscode-high-contrast pre code { color: white }
.vscode-light code { color: #A31515 }
.vscode-dark code { color: #D7BA7D }
.vscode-light pre:not(.hljs),.vscode-light code>div { background-color: rgba(220, 220, 220, 0.4) }
.vscode-dark pre:not(.hljs),.vscode-dark code>div { background-color: rgba(10, 10, 10, 0.4) }
.vscode-high-contrast pre:not(.hljs),.vscode-high-contrast code>div { background-color: rgb(0, 0, 0) }
.vscode-high-contrast h1 { border-color: rgb(0, 0, 0) }
.vscode-light table>thead>tr>th { border-color: rgba(0, 0, 0, 0.69) }
.vscode-dark table>thead>tr>th { border-color: rgba(255, 255, 255, 0.69) }
.vscode-light h1,.vscode-light hr,.vscode-light table>tbody>tr+tr>td { border-color: rgba(0, 0, 0, 0.18) }
.vscode-dark h1,.vscode-dark hr,.vscode-dark table>tbody>tr+tr>td { border-color: rgba(255, 255, 255, 0.18) }
.vscode-light blockquote,.vscode-dark blockquote { background: rgba(127, 127, 127, 0.1); border-color: rgba(0, 122, 204, 0.5) }
.vscode-high-contrast blockquote { background: transparent; border-color: #fff }
.hljs-comment,.hljs-quote { color: #8e908c }
.hljs-variable,.hljs-template-variable,.hljs-tag,.hljs-name,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-deletion { color: #c82829 }
.hljs-number,.hljs-built_in,.hljs-builtin-name,.hljs-literal,.hljs-type,.hljs-params,.hljs-meta,.hljs-link { color: #f5871f }
.hljs-attribute { color: #eab700 }
.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition { color: #718c00 }
.hljs-title,.hljs-section { color: #4271ae }
.hljs-keyword,.hljs-selector-tag { color: #8959a8 }
.hljs { display: block; color: #4d4d4c; padding: 0.5em }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: bold }
body { font-family: "Meiryo", "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback" }
pre { background-color: #f8f8f8; border: 1px solid #cccccc; white-space: pre-wrap }
pre:not(.hljs) { padding: 23px; line-height: 19px }
blockquote { background: rgba(127, 127, 127, 0.1); border-color: rgba(0, 122, 204, 0.5) }
.emoji { height: 1.4em }
:not(pre):not(.hljs)>code { color: #C9AE75; font-size: inherit }
.page { page-break-after: always }
原文地址:https://www.cnblogs.com/DannielZhang/p/9192510.html