剑指 Offer 03. 数组中重复的数字
思路:
因为所有数字都在 0~n-1 的范围内,且正好有n个数字,也就是说
每个数字都可以放在自己大小所对应的位置上
因此我们可以直接遍历数组
将遍历到的数字放在他们对应的位置上,如果发现对应位置被与自己相同的数字占了 就说明有重复数字
class Solution {
public:
int findRepeatNumber(vector<int>& nums) {
for(int i=0;i<nums.size();i++){
while(nums[i]!=i){
if(nums[i]==nums[nums[i]]) return nums[i];
swap(nums[i],nums[nums[i]]);
}
}
return -1;
}
};
class Solution {
public int findRepeatNumber(int[] nums) {
for(int i=0;i<nums.length;i++){
while(i!=nums[i]){
if(nums[i]==nums[nums[i]]) return nums[i];
int temp=nums[i];
nums[i]=nums[nums[i]];
nums[temp]=temp;
}
}
return -1;
}
}
剑指 Offer 53 - I. 在排序数组中查找数字 I
思路:
简单的二分模板题,通过二分,找到第一个大于等于target的位置x1,再找到第一个大于target的位置x2, ans=x2-x1
class Solution {
public:
int search(vector<int>& nums, int target) {
if(!nums.size()) return 0;
int l=0,r=nums.size()-1;
// 先找第一个大于等于target的下标
while(l<r){
int mid=l+r>>1;
if(nums[mid]>=target) r=mid;
else l=mid+1;
}
// 如果nums[l]依然不满足 >= target
// x1就还要后移一位
int x1=l+!(nums[l]>=target);
l=0,r=nums.size()-1;
// 找第一个大于target的下标
while(l<r){
int mid=l+r>>1;
if(nums[mid]>target) r=mid;
else l=mid+1;
}
int x2=l+!(nums[l]>target);
return x2-x1;
}
};
class Solution {
public int search(int[] nums, int target) {
if(nums.length==0) return 0;
int l=0,r=nums.length-1;
while(l<r){
int mid=l+r>>1;
if(nums[mid]>=target) r=mid;
else l=mid+1;
}
int x1=l;
if(! (nums[l]>=target) ) x1++;
l=0;
r=nums.length-1;
while(l<r){
int mid=l+r>>1;
if(nums[mid]>target) r=mid;
else l=mid+1;
}
int x2=l;
if(! (nums[l]>target) ) x2++;
return x2-x1;
}
}
剑指 Offer 53 - II. 0~n-1中缺失的数字
思路:
直接对数组求和,再通过等差数列前n项和公式减去数组值即可
class Solution {
public:
int missingNumber(vector<int>& nums) {
int n=nums.size();
int sm=n*(n+1)/2;
for(auto it:nums) sm-=it;
return sm;
}
};
class Solution {
public int missingNumber(int[] nums) {
int n=nums.length;
int sum=(n*(n+1))/2;
for(int i=0;i<nums.length;i++){
sum-=nums[i];
}
return sum;
}
}