版权声明:欢迎评论交流,转载请注明原作者。 https://blog.csdn.net/m0_37809890/article/details/88362116
事实证明,我的手生了很多…练习吧!
目标
在合适的复杂度下,尽可能快地完成程序,同时知道怎么进一步优化。
1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
使用哈希表,边扫描边保存,复杂度O(1),O(n)
class Solution
{
public:
vector<int> twoSum(vector<int>& nums, int target)
{
unordered_map<int, int> mp; //num->id
int ans1 = 0, ans2 = 0;
for(int i=0;i<nums.size();++i)
{
int need = target-nums[i];
if(mp.count(need))
{
ans1 = mp[need], ans2 = i;
break;
}
mp[nums[i]] = i;
}
return {ans1,ans2};
}
};
2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 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) {
ListNode *res = new ListNode(0), *sum = res;
int carry = 0;
while(l1 || l2)
{
sum = (sum->next = new ListNode(carry));
if(l1)
{
sum->val += l1->val;
l1 = l1->next;
}
if(l2)
{
sum->val += l2->val;
l2 = l2->next;
}
carry = sum->val>=10;
sum->val %= 10;
}
if(carry)
sum->next = new ListNode(1);
return res->next;
}
};
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
边界情况:字符串有可能为空串!
顺序扫一遍,维护两个值now和lim:
now:当前下标值;
lim:以now为结尾向前匹配,第一个出现重复的位置。
lim每次和now位置字符的上一次出现位置取较大值。
遍历每个now,取最大的now-lim就是答案。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int last_occurr[256], ans = 0;
memset(last_occurr, -1, sizeof(last_occurr));
for(int now=0, lim=-1; now<s.size(); ++now)
{
lim = max(lim, last_occurr[s[now]]);
last_occurr[s[now]] = now;
ans = max(ans, now-lim);
}
return ans;
}
};