Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
(1)问题分析
这是查找问题,在不增加空间消耗的情况下,选择顺序查找,时间复杂度O(n);增加几个变量,可以实现二分查找时间复杂度O(log(n));为每个元素计算一个hash值可以实现hashmap实现常数时间下的查找,时间复杂度O(1)。题目中没有对空间的限制,且数组没排序,所以适合采用hashmap,根据题目要求,应该需要查找两次,第一个值的下标没有约束,应该遍历得到i,第二个值的下标,通过target-num[i]这个约束,用hashmap得到。
(2)代码编写
class Solution{
public:
vector<int> twosum(vector<int>& nums,int target){
vector<int> res;
unordered_map<int,int> second_search;
for(int i=0;i<nums.size;i++){
second_search[num[i]]=i;//值为key,下标为value,根据值查找下标
}
for(int i=0;i<num.size;i++){
int sec = target-nums[i];
if(second_search.count(sec)&&second_search[sec]!=i){
res.push_back(i);
res.push_back(second_search[t]);
break;
}
}
return res;
}
};
You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
(1)问题分析
342+564 = 807,之所以从个位开始是方便我们做加法
链表的基本使用
(2)代码编写
struct ListNode {
int val; //当前结点的值
ListNode *next; //指向下一个结点的指针
ListNode(int x) : val(x), next(NULL) {} //初始化当前结点值为x,指针为空
};
class Solution{
private:
int numa;
int numb;
public:
ListNode* add(ListNode*l1, ListNode*l2){
int sum = 0;
int jin = 0;
ListNode* p = ListNode(-1);
ListNode* cur = p;
while(l1||l2){
numa = l1? l1->val:0;
numb = l2? l2->val:0;
sum = numa + numb + jin;
jin = sum/10;
sum = sum%10;
cur->next = ListNode(sum);
cur = cur->next();
if(l1) l1 = l1->next;
if(l2) l2 = l2->next;
}
if(jin) cur->next = ListNode(jin);
return p->next;
}
};
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequenceand not a substring.
(1)问题分析
遍历一遍字符串,维护一个滑动窗口,向右扩展的时候,判断扩展字符是否出现在滑动窗口中,未出现长度加一,出现过左边界向右平移。判断方式可用哈希表(key为字符,value为下标),当前字母未出现,或者出现位置小于左边界。
(2)代码编写
class Solution{
public:
int longestSubString(string s){
int res=0,left=0,right=0;
unordered_map<char,int> lastExitChar;
for(right; right<s.size();right++){
//不存在这个字符,或者未出现在滑动窗口里
if(lastExitChar.count(s[right])==0||lastExitChar[s[right]]<left){
res = max(res, right-left+1);
}else{//存在于滑动窗口里
left = lastExitChar[s[right]]+1;
}
lastExitChar[s[right]] = right;
}
return res;
}
};
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
(1)问题分析
想要log级别的时间效率,肯定不能遍历,要剪枝,尽可能多的排除掉不可能的选项。实现时采用迭代的方法,传入剪枝后的数组与中值在剪枝后的数组中的排位k。
为了保证思路尽可能简单,代码编写不追求简洁,追求思路符合直观
尽可能将边界情况拉出来单独处理
下标尽可能保持一致都从0开始;有语意,保证逻辑正确
(2)代码编写
class Solution{
public:
double findmid(vector<int>& num1,vector<int>& num2){
if((num1.size()+num2.size())%2==1){
return findkth(num1,0,num2,0,(num1.size()+num2.size())/2-1);//k指下标
}else{
return (findkth(num1,0,num2,0,(num1.size()+num2.size())/2-1)+findkth(num1,0,num2,0,(num1.size()+num2.size())/2))/2;
}
}
int findkth(vector<int>& num1,int i,vector<int>& num2,int j,int k){
if(i==num1.size()){return num2[j+k];}//i是直接用在num1的下标中的
if(num1.size()>num2.size()){return findkth(num2,j,num1,i,k);}
if(k==1){return min(num1(0),num2(0));}
int pa = min(num1.size()-1,i+k/2),pb = j-pa+i+k;
if(num1[pa]<num2[pb]){
return findkth(num1,pa,num2,j,k-pa+i);
}else if(num1[pa]>num2[pb]){
return findkth(num1,i,num2,pb,k-pb+j);
}else{
return num1[pa];
}
}
};