1 无重复字符的最长子串
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例:
给定 "abcabcbb"
,没有重复字符的最长子串是 "abc"
,那么长度就是3。
给定 "bbbbb"
,最长的子串就是 "b"
,长度是1。
给定 "pwwkew"
,最长子串是 "wke"
,长度是3。请注意答案必须是一个子串,"pwke"
是 子序列 而不是子串。
起初尝试性地做了一下,就有了下面的实现,但是最后有一个特别长的串超时,时间复杂度为O(n^2)。
实现一:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<char> um;
int a,b=0,pos,max=0;
int len=s.length();
for(int i=0;i<len;++i)
{
for(int j=i;j<len;++j)
{
if(count(um.begin(),um.end(),s[j]))
{
max=max>um.size()?max:um.size();
um.clear();
}
else
{
um.push_back(s[j]);
max=max>um.size()?max:um.size();
}
}
um.clear();
}
return max;
}
};
接着想着怎样将时间复杂度变为O(n),就有
实现二:
class Solution {
public:
int lengthOfLongestSubstring(string str) {
int max=0;
int begin=1;
map<char,int> um;
char a;
for(int i=1;i<=str.length();++i)
{
a=str[i-1];
if(um[a]>=begin)
{
begin=um[a]+1;
um[a]=i;
}
else
{
um[a]=i;
max=max>(i-begin+1)?max:(i-begin+1);
}
}
return max;
}
};
实现三:
class Solution {
public:
int lengthOfLongestSubstring(string str) {
int maxlen = 0;
int n = str.length();
int * next = (int*)malloc(sizeof(int)*n); //next[i]记录了下一个与str[i]重复的字符的位置
int * first = (int*)malloc(sizeof(int)*(n+1)); //first[i]记录str[i]后面最近的一个重复点
int hash[256];
memset(hash,n,sizeof(hash)); //注意memset并不是将数组初始化为“n”这个数值
first[n] = n;
for(int i=n-1; i>=0; i--)
{
next[i] = hash[str[i]];
hash[str[i]] = i;
if (next[i] < first[i+1])
first[i] = next[i];
else
first[i] = first[i+1]; //生成first[]表,复杂度是O(N)的
maxlen=(first[i]-i) > maxlen ? (first[i]-i) : maxlen;
}
free(first);
free(next);
return maxlen;
}
};

2 两数相加
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
实现:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
if(l1==NULL || l2==NULL)
return NULL;
int tmp1,tmp2=0;
ListNode *p,*q;
p=q=new ListNode(0);
while(l1 || l2)
{
tmp1=(l1?l1->val:0)+(l2?l2->val:0);
q->val=(tmp1+tmp2)%10;
tmp2=(tmp1+tmp2)/10;
if(l1) l1=l1->next;
if(l2) l2=l2->next;
if(!l1&&!l2)
{
if(tmp2!=0)
q->next=new ListNode(tmp2);
break;
}
q->next=new ListNode(0);
q=q->next;
}
return p;
}
};
3 两数之和
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例:
给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
实现:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int len = nums.size();
vector<int> tmp;
for(int i=0;i<len;++i)
{
for(int j=i+1;j<len;++j)
{
if(nums[i]+nums[j]==target){
tmp.push_back(i);
tmp.push_back(j);
break;
}
}
}
return tmp;
}
};