①两数相加
给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807
1.此题解决思想比较简单,直接设置一个进位carry,由于链表是按照逆序存储的,计算两数之和就可以直接从首节点开始计算求和,然后每次求得的和需要计算出该位的进位,即新进位carry = sum/10,在这里需要创建一个新链表用来存储求得的和(通过new创建),然后依次计算每一位之和并加到新链表之中,若某个链表达到尾部,则继续计算另一个链表,遍历完之后,观察进位carry是否存在进位,若存在进位则将1加到新链表尾部,最后返回新链表:
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* dummyRoot = new ListNode(0); //创建新链表存储求和数据
ListNode* p = dummyRoot; //定义指针p指向新链表
int carry = 0;
while (l1 || l2) //只有同时为空时,才退出
{
int x = l1 ? l1->val : 0; //判断链表l1是否为空,不为空则取出数据
int y = l2 ? l2->val : 0; //判断链表l2是否为空,不为空则取出数据
int sum = x + y + carry; //计算两数之和
carry = sum/10; //计算新进位
p->next = new ListNode(sum%10); //创建新链表中的新节点
p = p->next;
if (l1) //如果不为空,继续遍历
l1 = l1->next;
if (l2)
l2 = l2->next;
}
if (carry == 1) //判断是否存在进位,存在则把1加到新链表中
p->next = new ListNode(1);
return dummyRoot->next;
}
};
2.该题还有一种变形,即两个数不是按照逆序存在链表中,而是正序,有兴趣可以参考下Grandyang的博客,具体做法有两种,一种是将链表翻转,然后使用上述的方法求和;另一种不采用翻转链表,有点复杂,感兴趣的同学可以自己去了解。。。
②无重复字符的最长字串
给定一个字符串,找出不含有重复字符的最长子串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 无重复字符的最长子串是 "abc",其
长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 无重复字符的最长子串是 "b"
,其长度为 1。
示例 3:
输入: "pwwkew" 输出: 3 解释: 无重复字符的最长子串是"wke"
,其长度为 3。 请注意,答案必须是一个子串,"pwke"
是一个子序列 而不是子串。
1.使用set容器存储字符,如果之前未出现则存入set中,如果出现相同字符则从上一个left开始删除,删除到重复字符为止,其中记录下最大子串长度:
具体分析:
若字符串为abbca
首先i=0,存入set,此时set中存有字符a,更新cnt为1
i=1,没有相同,存入set,此时set中存有字符a、b,更新cnt为2
i=2,出现相同字符b,则从上一个left = 0开始删除,删除后set中无元素,此时st.size()为0
删除过后i=2,此时set中没有相同,存入b,st.size()为1,小于之前cnt,不更新
i=3,存入c,此时st.size()为2,不更新
i=4,存入a,此时st.size()为3,更新cnt为3,则此为最大长度,最大字串为bca
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int cnt = 0,left = 0,n = s.size();
unordered_set<char> st; //保存出现的字符
int i = 0;
while (i < n)
{
if (!st.count(s[i])) //未出现相同字符,则将字符插入set中,并更新子串长度为当前最大
{
st.insert(s[i++]); //插入当前字符,下移一位
cnt = max(cnt, (int)st.size());
}
else
st.erase(s[left++]); //出现相同字符则从上一个left开始删除,直到重复字符为止
}
return cnt;
}
};
2.使用hashmap来建立字符与其位置之间的联系,具体使用left标记重复字符的位置,根据该left得出最大长度:
具体分析:
若字符串为abbca
根据该思路,首先建立联系
i=0:left为0,字符‘a'位置为1,res长度为1
i=1:left为0,字符’b‘位置为2,res长度为2
i=2:出现重复字符’b',此时更新left的位置,使其指向上一个‘b’出现的位置2,更新新‘b'的位置为3,更新res长度为1
i=3:left为2,字符‘c’位置为4,res长度为2
i=4:left为2,字符’a‘位置更新为5,res长度更新为3
返回3
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int res = 0, left = 0, i = 0, n = s.size();
unordered_map<char, int> m; //建立字符与其位置的联系
for (int i = 0; i < n; ++i) { //遍历数组,若出现重复字符则更新left的位置,使其指向重复字符
left = max(left, m[s[i]]);
m[s[i]] = i + 1;
res = max(res, i - left + 1); //根据left计算最大长度
}
return res;
}
};