1.Two Sum
一次哈希:
将数值作为索引,在哈希表中找此时数值对应的另一个数值,若存在则取出该数值的编号,若不存在则将此时的数值和它的编号存入哈希表,以供后面使用。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
map<int,int> m;
vector<int> ans;
int len = nums.size();
for(int i=0;i<len;i++){
int n = target - nums[i];
if(m.find(n) != m.end()){
ans.push_back(m[n]);
ans.push_back(i);
return ans;
}
m[nums[i]] = i;
}
return ans;
}
};
2.Add Two Numbers
考虑多种情况:
链表可能不一样长,最后一位也可能会进位(最后需要再判断进位carry)。
/**
* 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* index = new ListNode();
ListNode* ans = index;
int carry = 0;
while(l1 != NULL && l2 != NULL){
index->next = new ListNode();
index = index->next;
int sum = l1->val + l2->val + carry;
if(sum>9){
sum = sum - 10;
carry = 1;
}
else
carry = 0;
index->val = sum;
l1 = l1->next;
l2 = l2->next;
}
if(l1 == NULL && l2 != NULL)
l1 = l2;
while(l1 != NULL){
index->next = new ListNode();
index = index->next;
int sum = l1->val + carry;
if(sum>9){
sum = sum - 10;
carry = 1;
}
else
carry = 0;
index->val = sum;
l1 = l1->next;
}
if(carry == 1){
index->next = new ListNode();
index = index->next;
index->val = carry;
}
return ans->next;
}
};
3.Longest Substring Without Repeating Characters
动态规划:
判断字符串为空,返回0。
判断字符串不为空:动态规划:局部最优 --> 整体最优
从字符串第二个字符开始判断到字符串的最后一个字符。
记录两个数据:
-
到达该字符时 满足要求的字符串的 最大长度:ans
-
到达该字符时 以该字符串结尾的 满足要求的字符串的 长度:dp
(只有加入后面来的字符,才可能使得 满足要求的字符串 更长)
每判断一个字符,比较一次 ans 和 dp 的大小,保证 局部最优。
最后的 ans 便是答案:整体最优。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.empty())
return 0;
int len = s.length();
int ans = 1,dp = 1,temp = 0;
for(int i=1;i<len;i++){
for(temp=0;temp<dp;temp++){
if(s[i] == s[i-1-temp])
break;
}
dp = temp+1;
ans = max(ans,dp);
}
return ans;
}
};
4.Median of Two Sorted Arrays
二分法:
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int len1 = nums1.size();
int len2 = nums2.size();
if(len1 > len2)
return findMedianSortedArrays(nums2,nums1);
int mid = (len1 + len2 + 1)/2;
int min1 = 0, max1 = len1,i,j;
while(min1 <= max1){
i = (min1 + max1)/2;
j = mid - i;
if(i < len1 && nums1[i] < nums2[j-1])
min1 = i+1;
else if(i > 0 && nums1[i-1] > nums2[j])
max1 = i-1;
else{
double max_of_left = max(i > 0 ? nums1[i-1]: INT_MIN,
j > 0 ? nums2[j-1]: INT_MIN);
if((len1 + len2) & 1)
return max_of_left;
double min_of_right = min(i < len1 ? nums1[i]: INT_MAX,
j < len2 ? nums2[j]: INT_MAX);
return 0.5 * (max_of_left + min_of_right);
}
}
return -1;
}
};
5.Longest Palindromic Substring
动态规划:
初始化长度为 1 的回文子串:dp[ i ] [ i ];
初始化长度为 2 的回文子串:
需要满足:s [ i ] = s [ i+1 ],dp[ i ] [ i+1 ] 就为 1;
循环判断长度从 3 到 s.length() 的回文子串:设此时回文子串的长度为 n
循环回文子串的开始位置:i,从 0 开始,到 s.length() - n 结束。
需要满足:s [ i ] = s [ i+n-1 ];
并且从 i+1 开始,到 i+n-2 结束的子串为回文子串,即 dp[ i+1 ] [ i+n-2 ] = 1。
循环的过程中不断更新回文子串的最大长度和开始位置。
class Solution {
public:
string longestPalindrome(string s) {
int len = s.size();
if(len == 0 || len == 1)
return s;
int start = 0,maxlen = 1;
vector<vector<int>> dp(len,vector<int>(len));
for(int i=0;i<len;i++){
dp[i][i] = 1;
if(i < len-1 && s[i] == s[i+1]){
dp[i][i+1] = 1;
maxlen = 2;
start = i;
}
}
for(int n = 3;n <= len;n++){
for(int i=0;i<=len-n;i++){
if(s[i] == s[i+n-1] && dp[i+1][i+n-2] == 1){
dp[i][i+n-1] = 1;
if(maxlen < n){
start = i;
maxlen = n;
}
}
}
}
return s.substr(start,maxlen);
}
};
中心扩展:
把字符串的某个字符,或者是某两个相邻字符之间的位置作为中心;
以中心为基准,向两边扩展,如果两边相同,则为回文子串。
循环遍历字符串中的中心位置,讨论以此为中心的回文子串。
不断更新回文子串的最大长度和开始位置。
class Solution {
public:
string longestPalindrome(string s) {
int len = s.length();
if(len == 0 || len == 1)
return s;
int start = 0,maxlen = 1;
for(int i=0;i<len;i++){
int begin = i,end = i;
while(begin-1 >= 0 && end+1 < len){
if(s[begin-1] == s[end+1]){
begin = begin -1;
end = end + 1;
if(maxlen < (end - begin + 1)){
maxlen = end - begin + 1;
start = begin;
}
}
else
break;
}
begin = i;
end = i+1;
while(begin >= 0 && end < len){
if(s[begin] == s[end]){
if(maxlen < (end - begin + 1)){
maxlen = end - begin + 1;
start = begin;
}
begin -= 1;
end += 1;
}
else
break;
}
}
return s.substr(start,maxlen);
}
};