(1)二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
-
解題思路:
-
采用二分查找方法,当nums[mid]==target时就返回mid;当nums[mid]>target时低位要mid+1,接着继续判断;当nums[mid]<target时高位要mid-1,接着继续判断;
class Solution {
public:
int search(vector<int>& nums, int target) {
int low =0,high=nums.size()-1,mid=0;
while(low<=high){
mid=(low+high)>>1;
if(nums[mid]==target){
return mid;
}else if(nums[mid]>target){
high=mid-1;
}else{
low=mid+1;
}
}
return -1;
}
};
(2)两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例 2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]
- 解题思路:
- 先建一个新的链表1,接着将旧的两链表的数值逐段相加,然后又新建链表2为旧的两链表和的取余,链表1与链表2相连,当有需要进位时就给下一次旧的两链表和相加,以此类推直到旧的两链表的指向为空为止。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
// ListNode*root = new ListNode(0);
// ListNode*head=root;
// int jinwei=0;
// while(l1!=nullptr||l2!=nullptr||jinwei!=0){
// int l1val=l1!=nullptr?l1->val:0;
// int l2val=l2!=nullptr?l2->val:0;
// int sumval=l1val+l2val+jinwei;
// jinwei=sumval/10;
// ListNode*sumNode=new ListNode(sumval%10);
// head->next=sumNode;
// head=sumNode;
// if(l1!=nullptr) l1=l1->next;
// if(l2!=nullptr) l2=l2->next;
// }
// return root->next;
ListNode*head=new ListNode(0);
ListNode*current=head;
int carry=0;
while(carry!=0||l1!=nullptr||l2!=nullptr){
if(l1!=nullptr){
carry+=l1->val;
l1=l1->next;
}
if(l2!=nullptr){
carry+=l2->val;
l2=l2->next;
}
current->next=new ListNode(carry%10);
current=current->next;
carry/=10;
}
return head->next;
}
};
(3)无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
-
示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 -
示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。 -
示例 3:
输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。 -
示例 4:
输入: s = “”
输出: 0
- 解题思路:
- 1)滑动窗口
什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
如何移动?
我们只要把队列的左边的元素移出就行了,直到满足题目要求!
一直维持这样的队列,找出队列出现最长的长度时候,求出解!
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0) return 0;
unordered_set<char> lookup;
int maxStr = 0;
int left = 0;
for(int i = 0; i < s.size(); i++){
while (lookup.find(s[i]) != lookup.end()){
lookup.erase(s[left]);
left ++;
}
maxStr = max(maxStr,i-left+1);
lookup.insert(s[i]);
}
return maxStr;
}
};
2)利用ascii码解题
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int arr[128];
for(int i=0;i<128;i++){
arr[i]=-1;
}
int n =s.length();
int res=0;
int start=0;
for(int i=0;i<n;i++){
int index=char(s[i]);
start=max(start,arr[index]+1);
res=max(res,i-start+1);
arr[index]=i;
}
return res;
}
};
(4)寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
- 示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
- 示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
- 示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
- 示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
- 示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
if(nums1.size()==0&nums2.size()==1||nums1.size()==1&&nums2.size()==0){
if(nums1.size()==1&&nums2.size()==0){
return double(nums1[0]);
}else if(nums1.size()==0&nums2.size()==1){
return double(nums2[0]);
}
}
vector<int>sum;
for(auto a:nums1){
sum.push_back(a);
}
for(auto a:nums2){
sum.push_back(a);
}
sort(sum.begin(),sum.end());
if(sum.size()%2==1){//单
cout<<"单"<<endl;
return double(sum[sum.size()/2]);
}else{
cout<<"双"<<endl;
int totalSum=sum.size()/2;
return double((sum[totalSum]+sum[totalSum-1]))/double(2);
}
return 0;
}
};