【001 Two Sum】
题目大意:给一个数组,找出其中是否有两个数之和等于给定的值。类似的还有3 sum ,4 sum ..等 K sum 问题。其实原理是差不多的,这样想:先取出一个数,那么我只要在剩下的数字里面找到两个数字使得他们的和等于(target – 那个取出的数)。
分析:
方法一:暴力找过去复杂度是 O(n^2),不建议面试时使用
#include <iostream>
#include <vector>
using namespace std;
class Solution{
public:
vector<int> twoSum(vector<int>& nums, int target){
vector<int> numTemp;
for (int i = 0; i < nums.size(); i++)
{
for (int j = i + 1; j < nums.size(); j++)
{
if ((nums[i]+nums[j])==target)
{
numTemp.push_back(i);
numTemp.push_back(j);
return numTemp;
}
}
}
return numTemp;
}
};
int main(){
vector<int> nums;
vector<int> res;
nums.push_back(2);
nums.push_back(7);
nums.push_back(11);
nums.push_back(15);
vector<int>::iterator iter;
for (iter = nums.begin(); iter != nums.end();iter++)
{
cout<<*iter<<' ';
}
cout << endl;
Solution s;
res = s.twoSum(nums,9);
for (iter = res.begin(); iter != res.end();iter++)
{
cout << *iter << ' ';
}
system("pause");
}
方法二:先排序,然后用双指针从开头和结尾同时向中间查找,原理也比较简单。复杂度O(nlogn)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Solution{
public:
vector<int> twoSum(vector<int>& nums, int target){
int sz = nums.size();
int left = 0, right = sz - 1, sum = 0;
vector<int> sorted(nums);
sort(sorted.begin(), sorted.end());
vector<int> index;
while (left < right)
{
sum = sorted[left] + sorted[right];
if (sum == target)
{
//find the answer
for (int i = 0; i < sz; i++)
{
if (nums[i] == sorted[left])
index.push_back(i);
else if (nums[i] == sorted[right])
index.push_back(i);
if (index.size() == 2)
return index;
}
}
else if (sum > target)
{
right--;
}
else
{
left++;
}
}
}
};
int main(){
vector<int> nums;
vector<int> res;
nums.push_back(3);
nums.push_back(2);
nums.push_back(4);
//nums.push_back(15);
vector<int>::iterator iter;
for (iter = nums.begin(); iter != nums.end(); iter++)
{
cout << *iter << ' ';
}
cout << endl;
Solution s;
res = s.twoSum(nums, 6);
for (iter = res.begin(); iter != res.end(); iter++)
{
cout << *iter << ' ';
}
system("pause");
}
方法三:使用HashMap。把每个数都存入map中,然后再逐个遍历,查找是否有 target – nubmers[i]。时间复杂度 O(n)
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
class Solution{
public:
vector<int> twoSum(vector<int>& nums, int target){
vector<int> res;
int length = nums.size();
map<int, int>mp;
for (int i = 0; i < length;i++)
mp[nums[i]] = i;
map<int, int>::iterator it = mp.end();
for (int i = 0; i < length;i++)
{
it = mp.find(target - nums[i]);
if (it->second == i)
{
continue;
}
if (it != mp.end())
{
res.push_back(min(i, it->second));
res.push_back(max(i, it->second));
break;
}
}
return res;
}
};
int main(){
vector<int> nums;
vector<int> res;
nums.push_back(3);
nums.push_back(2);
nums.push_back(4);
//nums.push_back(15);
vector<int>::iterator iter;
for (iter = nums.begin(); iter != nums.end(); iter++)
{
cout << *iter << ' ';
}
cout << endl;
Solution s;
res = s.twoSum(nums, 6);
for (iter = res.begin(); iter != res.end(); iter++)
{
cout << *iter << ' ';
}
system("pause");
}
【002 Add Two Numbers】
题目大意:给两个链表代表两个反向存储的数字,返回他们的和,用链表表示。
#include <iostream>
using namespace std;
struct ListNode{
int val;
ListNode *next;
ListNode(int x) :val(x), next(NULL){}
};
class Solution{
public:
ListNode* addTwoNumbers(ListNode*l1, ListNode*l2){
ListNode *ans = NULL, *last = NULL;
int up = 0;
while (NULL != l1 && NULL != l2)
{
int temp = l1->val + l2->val + up;
up = temp / 10;
//第一个单独处理
if (NULL == last)
{
ans = new ListNode(temp % 10);
last = ans;
}
else
last = push_back(last, temp % 10);
l1 = l1->next;
l2 = l2->next;
}
while (NULL != l1)
{
int temp = l1->val + up;
last = push_back(last, temp % 10);
up = temp / 10;
l1 = l1->next;
}
while (NULL != l2)
{
int temp = l2->val + up;
last = push_back(last, temp % 10);
up = temp / 10;
l2 = l2->next;
}
if (0 != up)
{
ListNode *l = new ListNode(up);
last->next = l;
}
return ans;
}
//在末尾添加值val,返回链表尾
ListNode *push_back(ListNode *last, int val){
ListNode *l = new ListNode(val);
last->next = l;
return l;
}
};
int main(){
ListNode *ln1 = new ListNode(2);
ListNode *ln2 = new ListNode(4);
ListNode *ln3 = new ListNode(3);
ln1->next = ln2;
ln2->next = ln3;
ListNode *n1 = new ListNode(5);
ListNode *n2 = new ListNode(6);
ListNode *n3 = new ListNode(4);
n1->next = n2;
n2->next = n3;
Solution s;
ListNode *pTemp = NULL;
pTemp = s.addTwoNumbers(ln1, n1);
while (NULL != pTemp)
{
cout << pTemp->val << ' ';
pTemp = pTemp->next;
}
system("pause");
return 0;
}
leetcode难度及面试频率