Two Sum哈希表的应用
通过哈希查找较快,时间复杂度为O(n)。
#include <iostream>
#include <vector>
#include <map>
using namespace std;
/*Two Sum in LeetCode.通过哈希查找.
*step1:建立哈希表map<int,int> mapping,key为numbers[i],value为Index即i
*step2:扫描数组numbers,在哈希表中查询是否有tagrget-numbers[i]
*/
class Solution {
public:
vector<int> twoSum(vector<int> &numbers, int target) {
int i;
map<int,int> mapping;
vector<int> result;
//建立哈希表
for(i=0;i<numbers.size();i++)
mapping[numbers[i]]=i;
//扫描numbers
for(i=0;i<numbers.size();i++)
{
int search=target-numbers[i];//要在hash表中查找的数字
//mapping.find(search)=mapping.end()表示未找到
//i!=mapping[search]表示不能是自身相加等于target
if(mapping.find(search)!=mapping.end()&& i!=mapping[search])//找到了
{
result.push_back(i+1);//index不是zero-based
result.push_back(mapping[search]+1);
return result;
}
}
//return result; 在if里返回否则会重复
}
};
int main()
{
int target=14;
vector<int> numbers={2, 7, 11, 15},b;
Solution s;
b=s.twoSum(numbers,target);
for(int i=0;i<b.size();i++)
cout<<b[i]<<" ";
return 0;
}
Add Two Number链表的应用
- 数字相加,当前为temp%10,进位为temp/10。
- temp用来存放两位数相加的结果,一定要初始化!
#include <iostream>
#include <vector>
using namespace std;
/*
* 本题两个数字相加和传统加法唯一的不同就是此题的加法是从左往右算的,进位也是从左往右进。
* 例子里给的就是
2 4 3
+ 5 6 4
——————————
7 0 8
* 正常加法应该先算3+4,接着4+6,进一位,最后2+5,加之前的进位1,得到8;
* 在本题就应该先算2+5,接着4+6,进一位到3+4中,3+4+1=8,最后得到708。
*/
//定义结构体
struct ListNode{
int val;
ListNode* next;
//初始化当前结点值为x,指针为空
ListNode(int x):val(x),next(NULL){} //new ListNode(0)
};
class Solution
{
public:
/*创建单链表*/
ListNode* createList(vector<int> &numbers)
{
int i;
ListNode* phead=new ListNode(numbers[0]);
ListNode* head=phead;
for(i=1;i<numbers.size();i++){
ListNode* node=new ListNode(numbers[i]);
phead->next=node;
phead=node;
}
cout<<"链表创建成功!\n";
return head;
}
/*打印链表*/
void printList(ListNode* head)
{
ListNode* phead=head;
while(phead!=NULL)
{
cout<<phead->val<<" ";
phead=phead->next;
}
cout<<"\n";
}
ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) {
ListNode* head1=l1;
ListNode* head2=l2;
ListNode* phead=new ListNode(0);
ListNode* head=phead;
if(head1==NULL && head2==NULL)
return NULL;
if(head1==NULL)
return head2;
if(head2==NULL)
return head1;
int temp=0;//temp记录两位相加的结果,一定要初始化!
while(head1!=NULL||head2!=NULL||temp!=0)
{
if(head1!=NULL)
{
temp+=head1->val;
head1=head1->next;
}
if(head2!=NULL)
{
temp+=head2->val;
head2=head2->next;
}
//cout<<temp%10<<" "<<temp/10<<"\n";
phead->next=new ListNode(temp%10);
phead=phead->next;
temp=temp/10;
}
return head->next;
}
};
int main()
{
ListNode* headA;
ListNode* headB;
ListNode* head;
vector<int> a={2,4,3};
vector<int> b={5,6,4};
Solution ll;
cout<<"A";
headA=ll.createList(a);
ll.printList(headA);
cout<<"B";
headB=ll.createList(b);
ll.printList(headB);
cout<<"AB链表合并之后的结果为:";
head=ll.addTwoNumbers(headA,headB);
ll.printList(head);
return 0;
}
Longest Substring Without Repeating Characters
通过HASH表找出最长子串的长度,采用窗口移动加max函数的思想!
#include <iostream>
#include <map>
using namespace std;
/*
"滑动窗口"
比如 abcabccc 当你右边扫描到abca的时候你得把第一个a删掉得到bca,
然后"窗口"继续向右滑动,每当加到一个新char的时候,左边检查有无重复的char,
然后如果没有重复的就正常添加,
有重复的话就左边扔掉一部分(从最左到重复char这段扔掉),在这个过程中记录最大窗口长度
*/
class Solution {
public:
//利用好Max函数
int lengthOfLongestSubstring(string s) {
int start=-1;//记录当前窗口子串的最左端,start从-1开始是因为i是从0开始,i-start则表示当前子串的长度
int num=0;//记录最长子串的长度
map<char,int> mapping;
for(int i=0;i<s.length();i++)
{
char c=s[i];
if(mapping.find(c)!=mapping.end())//出现重复
start=max(start,mapping[c]);
mapping[c]=i;
num=max(num,i-start);
}
return num;
}
};
int main()
{
string s="abcabcbb";
Solution ss;
cout<<"最长子串的长度为:"<<ss.lengthOfLongestSubstring(s);
return 0;
}