目录
33. Search in Rotated Sorted Array
81. Search in Rotated Sorted Array II
153. Find Minimum in Rotated Sorted Array
154. Find Minimum in Rotated Sorted Array II
738. Monotone Increasing Digits
33. Search in Rotated Sorted Array
Medium
3871407Add to ListShare
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
).
You are given a target value to search. If found in the array return its index, otherwise return -1
.
You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
Example 1:
Input: nums = [4,5,6,7,0,1,2], target = 0 Output: 4
Example 2:
Input: nums = [4,5,6,7,0,1,2], target = 3 Output: -1
class Solution {
public:
/*Runtime: 4 ms, faster than 80.01% of C++ online submissions for Search in Rotated Sorted Array.
Memory Usage: 7.9 MB, less than 100.00% of C++ online submissions for Search in Rotated Sorted Array.*/
int search(vector<int>& nums, int target) {
int mid = 0;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] < nums[i - 1]) {
mid = i; break;
}
}
int left, right;
if (mid - 1 < 0 || (nums[0] > target || nums[mid - 1] < target)) {
left = mid; right = nums.size() - 1;
}
else if (nums[mid]<target || nums.back()>target) {
left = 0; right = mid - 1;
}
else if(nums[0]==target) return 0;
else if(nums[mid-1]==target) return mid-1;
else if(nums[mid]==target) return mid;
else if(nums.back()==target) return nums.size()-1;
while (left <= right) {
mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else if (nums[mid] > target) right = mid - 1;
else return mid;
}
return -1;
}
};
81. Search in Rotated Sorted Array II
Medium
997417Add to ListShare
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,0,1,2,2,5,6]
might become [2,5,6,0,0,1,2]
).
You are given a target value to search. If found in the array return true
, otherwise return false
.
Example 1:
Input: nums = [2,5,6,0,0,1,2], target = 0
Output: true
Example 2:
Input: nums = [2,5,6,0,0,1,2], target = 3
Output: false
Follow up:
- This is a follow up problem to Search in Rotated Sorted Array, where
nums
may contain duplicates. - Would this affect the run-time complexity? How and why?
/*81. Search in Rotated Sorted Array II
二分法
Runtime: 8 ms, faster than 60.83% of C++ online submissions for Search in Rotated Sorted Array II.
Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Search in Rotated Sorted Array II.*/
bool search(vector<int>& nums, int target) {
int mid = 0;
for (int i = 1; i < nums.size(); i++) {
if (nums[i] < nums[i - 1]) {
mid = i; break;
}
}
int left, right;
if (mid - 1 < 0 || (nums[0] > target || nums[mid - 1] < target)) {
left = mid; right = nums.size() - 1;
}
else if (nums[mid]<target || nums.back()>target) {
left = 0; right = mid - 1;
}
else return true;
while (left <= right) {
mid = left + (right - left) / 2;
if (nums[mid] < target) left = mid + 1;
else if (nums[mid] > target) right = mid - 1;
else return true;
}
return false;
}
153. Find Minimum in Rotated Sorted Array
Medium
1639211Add to ListShare
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
).
Find the minimum element.
You may assume no duplicate exists in the array.
Example 1:
Input: [3,4,5,1,2] Output: 1
Example 2:
Input: [4,5,6,7,0,1,2] Output: 0
class Solution {
public:
/*Runtime: 4 ms, faster than 75.40% of C++ online submissions for Find Minimum in Rotated Sorted Array.
Memory Usage: 7.9 MB, less than 100.00% of C++ online submissions for Find Minimum in Rotated Sorted Array.*/
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<nums[right]) right=mid;
else if(nums[mid]>nums[right]) left=mid+1;
}
return nums[right];
}
};
154. Find Minimum in Rotated Sorted Array II
Hard
683191Add to ListShare
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7]
might become [4,5,6,7,0,1,2]
).
Find the minimum element.
The array may contain duplicates.
Example 1:
Input: [1,3,5] Output: 1
Example 2:
Input: [2,2,2,0,1] Output: 0
Note:
- This is a follow up problem to Find Minimum in Rotated Sorted Array.
- Would allow duplicates affect the run-time complexity? How and why?
class Solution {
public:
/*当数组中存在大量的重复数字时,就会破坏二分查找法的机制,
将无法取得 O(lgn) 的时间复杂度,又将会回到简单粗暴的 O(n),
比如这两种情况:{2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 2} 和
{2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2},可以发现,
当第一个数字和最后一个数字,还有中间那个数字全部相等的时候,
二分查找法就崩溃了,因为它无法判断到底该去左半边还是右半边。
这种情况下,将右指针左移一位(或者将左指针右移一位),略过一个相同数字,
这对结果不会产生影响,因为只是去掉了一个相同的,
然后对剩余的部分继续用二分查找法,在最坏的情况下,
比如数组所有元素都相同,时间复杂度会升到 O(n).
Runtime: 8 ms, faster than 59.29% of C++ online submissions for Find Minimum in Rotated Sorted Array II.
Memory Usage: 8 MB, less than 100.00% of C++ online submissions for Find Minimum in Rotated Sorted Array II.*/
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(left<right){
int mid=left+(right-left)/2;
if(nums[mid]<nums[right]) right=mid;
else if(nums[mid]>nums[right]) left=mid+1;
else right--;
}
return nums[right];
}
};
129. Sum Root to Leaf Numbers
Medium
100730Add to ListShare
Given a binary tree containing digits from 0-9
only, each root-to-leaf path could represent a number.
An example is the root-to-leaf path 1->2->3
which represents the number 123
.
Find the total sum of all root-to-leaf numbers.
Note: A leaf is a node with no children.
Example:
Input: [1,2,3] 1 / \ 2 3 Output: 25 Explanation: The root-to-leaf path 1->2 represents the number 12. The root-to-leaf path 1->3 represents the number 13. Therefore, sum = 12 + 13 = 25.
Example 2:
Input: [4,9,0,5,1] 4 / \ 9 0 / \ 5 1 Output: 1026 Explanation: The root-to-leaf path 4->9->5 represents the number 495. The root-to-leaf path 4->9->1 represents the number 491. The root-to-leaf path 4->0 represents the number 40. Therefore, sum = 495 + 491 + 40 = 1026.
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
/*Runtime: 4 ms, faster than 74.01% of C++ online submissions for Sum Root to Leaf Numbers.
Memory Usage: 11.5 MB, less than 100.00% of C++ online submissions for Sum Root to Leaf Numbers.*/
int sumNumbers(TreeNode* root) {
stack<TreeNode*> s;
int res=0;
TreeNode *pre=NULL;
string num="";
while(root || !s.empty()){
while(root){
s.push(root);
num+=(root->val+'0');
root=root->left;
}
TreeNode *tmp=s.top();
if(tmp->right==NULL || tmp->right==pre){
s.pop();
pre=tmp;
root=NULL;
if(tmp->right==NULL && tmp->left==NULL){
res+=stoi(num);
}
num=num.substr(0,num.size()-1);
}else root=tmp->right;
}
return res;
}
};
670. Maximum Swap
Medium
77255Add to ListShare
Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get.
Example 1:
Input: 2736 Output: 7236 Explanation: Swap the number 2 and the number 7.
Example 2:
Input: 9973 Output: 9973 Explanation: No swap.
Note:
- The given number is in the range [0, 108]
class Solution {
public:
/*Runtime: 0 ms, faster than 100.00% of C++ online submissions for Maximum Swap.
Memory Usage: 7.9 MB, less than 100.00% of C++ online submissions for Maximum Swap.*/
int maximumSwap(int num) {
vector<int> n;
vector<pair<int,int> > dp;
while(num){
n.push_back(num%10);
num/=10;
}
dp.push_back(make_pair(n[0],0));
for(int i=1;i<n.size();i++){
if(n[i]>dp.back().first)
dp.push_back(make_pair(n[i],i));
else dp.push_back(dp.back());
}
for(int i=dp.size()-1;i>=0;i--){
if(dp[i].first==n[i]) continue;
int tmp=n[i];
n[i]=dp[i].first;
n[dp[i].second]=tmp;
break;
}
int res=0;
for(int i=n.size()-1;i>=0;i--){
res=res*10+n[i];
}
return res;
}
};
321. Create Maximum Number
Hard
558196Add to ListShare
Given two arrays of length m
and n
with digits 0-9
representing two numbers. Create the maximum number of length k <= m + n
from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k
digits.
Note: You should try to optimize your time and space complexity.
Example 1:
Input:nums1 = [3, 4, 6, 5]nums2 = [9, 1, 2, 5, 8, 3]k = 5 Output:[9, 8, 6, 5, 3]
Example 2:
Input:nums1 = [6, 7]nums2 = [6, 0, 4]k = 5 Output:[6, 7, 6, 0, 4]
Example 3:
Input:nums1 = [3, 9]nums2 = [8, 9]k = 3 Output:[9, 8, 9]
#include"pch.h"
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
/*321. Create Maximum Number
Runtime: 224 ms, faster than 22.70% of C++ online submissions for Create Maximum Number.
Memory Usage: 24.5 MB, less than 80.00% of C++ online submissions for Create Maximum Number.*/
vector<int> mergeVector ( vector<int> nums1, vector<int> nums2){
//已经从nums1和nums2中取出元素了,现在混合,使之形成的整数最大
vector<int> res;
while (!nums1.empty() || !nums2.empty()) {
//vector可以直接比较大小
vector<int> &tmp = (nums1 > nums2) ? nums1 : nums2;
res.push_back(tmp[0]);
tmp.erase(tmp.begin());//tmp是nums1或nums2的地址,所以删除相当于删除nums1或nums2
}
return res;
}
vector<int> maxVector(vector<int> &nums, int k) {
//在一个nums里面选出k个,组成最大的
int drop = nums.size() - k;
vector<int> res;
for (auto num : nums) {
while (drop > 0 && !res.empty() && res.back() < num) {
res.pop_back();
--drop;
}
res.push_back(num);
}
res.resize(k);
return res;
}
vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
/*从nums1中取i个元素,从nums2中取k-i个元素,i的范围:
最小值:max(0,k-nums2.size())
最大值:min(nums1.size(),k)*/
int i;
int n1 = nums1.size(), n2 = nums2.size();
//这里需要使用n1和n2!!!
int down = 0 > (k - n2) ? 0 : (k - n2);
int up = n1 < k ? n1 : k;
vector<int> res;
for (i = down;i<=up; i++) {
cout << i << endl;
res = max(res, mergeVector(maxVector(nums1, i), maxVector(nums2, k - i)));
}
return res;
}
int main() {
vector<int> nums1 = { 3,4,6,5 }, nums2 = { 9,1,2,5,8,3,5 };
vector<int> res = maxNumber(nums1, nums2, 5);
for (int i = 0; i < res.size(); i++) cout << res[i] << " ";
return 0;
}
402. Remove K Digits
Medium
140679Add to ListShare
Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.
Note:
- The length of num is less than 10002 and will be ≥ k.
- The given num does not contain any leading zero
Example 1:
Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
Example 2:
Input: num = "10200", k = 1 Output: "200" Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
Example 3:
Input: num = "10", k = 2 Output: "0" Explanation: Remove all the digits from the number and it is left with nothing which is 0.
#include"pch.h"
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
/*402. Remove K Digits
n=num.size(),如果要去除k个,那么剩下n-k个,如何判断哪些数字应该去掉呢?
如果数字递增,那需要从后面移除最大的数字,
如果是乱序,单调栈:::只要发现当前的数字小于栈顶元素,就将栈顶元素移除,
开始遍历num的每一位,对于当前遍历到的数字c,进行while循环,
如果res不为空,且k>0,且res的最后一位>c,那么应该将res的最后一位移除,k-1
当跳出while循环后,将c加入res,最后将res的大小重设为n-k,
需要用一个while循环来去掉前面所有的0,然后返回时判断是否为空
Runtime: 4 ms, faster than 91.24% of C++ online submissions for Remove K Digits.
Memory Usage: 8.3 MB, less than 100.00% of C++ online submissions for Remove K Digits.*/
string removeKdigits1(string num, int k) {
string res = "";
int n = num.size(), keep = n - k;
for (char c : num) {
while (k && res.size() && res.back()>c) {
res.pop_back();
k--;
}
res.push_back(c);
}
res.resize(keep);
while (!res.empty() && res[0] == '0') res.erase(res.begin());
return res.empty() ? "0" : res;
}
/*Runtime: 4 ms, faster than 91.24% of C++ online submissions for Remove K Digits.
Memory Usage: 8.5 MB, less than 100.00% of C++ online submissions for Remove K Digits.*/
string removeKdigits(string num, int k) {
string res = "";
for (char c : num) {
while(k && res.size() && res.back()>c){
res.pop_back();
k--;
}
if (res.size() || c != '0') res.push_back(c);
//如果res为空,并且c为‘0’,那么这个c不放进去,在这一步杜绝了leading zero
}
while (res.size() && k) {
res.pop_back();
k--;
}
return res.empty() ? "0" : res;
}
int main() {
cout << removeKdigits("10200",1);
return 0;
}
738. Monotone Increasing Digits
Medium
34453Add to ListShare
Given a non-negative integer N
, find the largest number that is less than or equal to N
with monotone increasing digits.
(Recall that an integer has monotone increasing digits if and only if each pair of adjacent digits x
and y
satisfy x <= y
.)
Example 1:
Input: N = 10 Output: 9
Example 2:
Input: N = 1234 Output: 1234
Example 3:
Input: N = 332 Output: 299
Note: N
is an integer in the range [0, 10^9]
.
#include"pch.h"
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
/*738. Monotone Increasing Digits
Runtime: 0 ms, faster than 100.00% of C++ online submissions for Monotone Increasing Digits.
Memory Usage: 7.7 MB, less than 100.00% of C++ online submissions for Monotone Increasing Digits.*/
int monotoneIncreasingDigits(int N) {
/*≤N的单调递增整数*/
int res = 0;
vector<int> num, st;
while (N) {
num.push_back(N % 10);
N /= 10;
}
int start = -1;
for (int i = num.size() - 2; i >= 0; i--) {
if (num[i] < num[i + 1]) {
start = i + 1;
break;
}
}
if (start == -1) {
for (int i = num.size() - 1; i >= 0; i--) {
res = res * 10 + num[i];
}
return res;
}
while (start < num.size()) {
if (start + 1 < num.size() && num[start] > num[start + 1]) {
num[start] -= 1; break;
}
else {
start++;
}
}
if (start == num.size()) { num[start - 1]--; start--; }
for (int i = 0; i < start; i++) num[i] = 9;
for (int i = num.size() - 1; i >= 0; i--) {
res = res * 10 + num[i];
}
return res;
}
int main() {
cout << monotoneIncreasingDigits(322);
return 0;
}