目录
LeetCode34.在排序数组中查找元素的第一个和最后一个位置
LeetCode153.寻找旋转排序数组中的最小值
LeetCode154.寻找旋转排序数组中的最小值II
瞎暴力:面试这么写稳稳挂
二分:注意重复元素的处理情况
LeetCode852.山脉数组的峰顶索引
LeetCode230.二叉搜索树中第K小的元素
LeetCode671.二叉树中第二小的节点
LeetCode1237.找出给定方程的正整数解
瞎暴力
剪枝优化
思考二分:
LeetCode287.寻找重复数
哈希表
木桶法
LeetCode面试题08.03魔术索引
瞎暴力
利用有序数组性质
LeetCode面试题53-II.0~n-1中缺失的数字
在这道题中用左右指针和二分查找的时间一样,但时间复杂度不一样
class Solution {
public:
vector searchRange(vector& nums, int target) {
vector ans(2,-1);
if(nums.size()==0)
return ans;
int l = 0, r = nums.size()-1;
while(l=target)
r = m;
else
l = m + 1;
}
if(nums[l]!=target)
return ans;
ans[0] = l;
r = nums.size();
while(l
超级经典的二分,这里没有重复的数组,所以处理起来会比下一题简单很多!
class Solution {
public:
int findMin(vector& nums) {
int left = 0;
int right = nums.size()-1;
while(leftnums[right])
left = mid + 1;
else
right = mid;
}
return nums[left];
}
};
吐槽一句:这里是《剑指offer》上面的原题,但是剑指那本书对于这道题的思路讲解的非常棒,但是代码写的太垃圾了的,可读性很低!
class Solution {
public:
int minArray(vector& numbers) {
for(int i = 1; i
想一下,如果mid到right全部都是重复元素,没有最后一个else里的right--时候,是不是会出现死循环的情况?所以这里的这个点特别要注意!
class Solution {
public:
int findMin(vector& nums) {
int left = 0;
int right = nums.size()-1;
while(leftnums[right])
left = mid+1;
else if(nums[mid]
笨方法当然是找到最大值的下标然后垫底
class Solution {
public:
int peakIndexInMountainArray(vector& A) {
vector a(A.begin(),A.end());
sort(a.begin(),a.end());
int b = a[a.size()-1];//找到最大值
for(int i = 0;i
忽然发现不同二分,直接从左向右遍历,遇到右比作左大的情况就找到了
class Solution {
public:
int peakIndexInMountainArray(vector& A) {
for(int i=0;iA[i+1])//山峰出现
return i;
}
return 0;
}
};
一分钟搞了个中序遍历AC,还是没有用到二分,很失望
/**
* 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 {
private:
vector v;
public:
int kthSmallest(TreeNode* root, int k) {
InOrderTraver(root,k);
return v[k-1];
}
void InOrderTraver(TreeNode* root,int k){
if(root==NULL)
return;
InOrderTraver(root->left,k);
v.push_back(root->val);
if(v.size()==k)//到第K个就停下
return;
InOrderTraver(root->right,k);
}
};
又没用二分,遍历大法好,失望……
/**
* 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 {
private:
set s;
public:
int findSecondMinimumValue(TreeNode* root) {
PreOrderTraver(root);
if(s.size()<2)
return -1;
set::iterator it = s.begin();
it++;
return *it;
}
void PreOrderTraver(TreeNode* root){
if(root==NULL)
return;
s.insert(root->val);
PreOrderTraver(root->left);
PreOrderTraver(root->right);
}
};
一开始不很清楚,看一眼提示,瞬间用暴力AC
没有利用递增的性质,面试这么说就挂了
/*
* // This is the custom function interface.
* // You should not implement it, or speculate about its implementation
* class CustomFunction {
* public:
* // Returns f(x, y) for any given positive integers x and y.
* // Note that f(x, y) is increasing with respect to both x and y.
* // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
* int f(int x, int y);
* };
*/
class Solution {
public:
vector> findSolution(CustomFunction& customfunction, int z) {
vector> vv;
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
vector v;
if(customfunction.f(i,j)==z){
v.push_back(i);
v.push_back(j);
vv.push_back(v);
}
}
}
return vv;
}
};
/*
* // This is the custom function interface.
* // You should not implement it, or speculate about its implementation
* class CustomFunction {
* public:
* // Returns f(x, y) for any given positive integers x and y.
* // Note that f(x, y) is increasing with respect to both x and y.
* // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
* int f(int x, int y);
* };
*/
class Solution {
public:
vector> findSolution(CustomFunction& customfunction, int z) {
vector> vv;
for(int i=1;i<=1000;i++){
for(int j=1;j<=1000;j++){
vector v;
if(customfunction.f(i,j)==z){
v.push_back(i);
v.push_back(j);
vv.push_back(v);
}else if(customfunction.f(i,j)>z){//利用递增的性质将不可能的解法剔除,属于剪枝
break;
}
}
}
return vv;
}
};
因为是递增的,所有对每个x取值,最多只能由一个y值,再利用递增的性质,二分查找;
反过来,对于每个y取值,最多只能由一个x值满足;
所以,单独二分只能利用一个变量递增的性质,还是会有浪费啊!
最好的是双指针二分,这样一点时间浪费都没有,但是我懒啊,不做了哈哈哈下一题
还是贴一个别人的吧,其实思路构思出来的话一分钟也能A
vector> findSolution(CustomFunction& customfunction, int z) {
vector> res = {};
int x =1; int y = 1000;
while(x<=1000 && y>=1 ){
if(customfunction.f(x,y) == z) {
res.push_back({x,y});
++x;--y;
}
else if(customfunction.f(x,y)
class Solution {
public:
int findDuplicate(vector& nums) {
map m;
for(int i=0;i=2)
return nums[i];
}
return 0;
}
};
因为我们提前知道木桶下标值的范围,所以用木桶法代替哈希表法可以更为方便
class Solution {
public:
int findDuplicate(vector& nums) {
int a[nums.size()+1];
for(int i=1;i<=nums.size();i++)
a[i]= 0;
for(int i=0;i=2)
return nums[i];
}
return 0;
}
};
遇事不决量子力学,啥也不会直接暴力
根本就没有利用有序数组的性质,面试gg
class Solution {
public:
int findMagicIndex(vector& nums) {
int min = (1<<21);
for(int i=0;i
直接从头开始找最小,二分太浪费了吧?
class Solution {
public:
int findMagicIndex(vector& nums) {
for(int i=0;i
class Solution {
public:
int missingNumber(vector& nums) {
int left = 0;
int right = nums.size()-1;
while(left<=right){
int mid = (left+right)/2;
if(mid == nums[mid]) //以中间的数组下标是否对应数组值为判断标准
left = mid+1;
else
right = mid-1;
}
return left;
}
};