1.搜索旋转排序数组
class Solution {
public int search(int[] nums, int target) {
int n = nums.length;
if (n == 0) {
return -1;
}
if (n == 1) {
return nums[0] == target ? 0 : -1;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[0] <= nums[mid]) {
if (nums[0] <= target && target < nums[mid]) {
r = mid - 1;
} else {
l = mid + 1;
}
} else {
if (nums[mid] < target && target <= nums[n - 1]) {
l = mid + 1;
} else {
r = mid - 1;
}
}
}
return -1;
}
}
2.组合就和
class Solution {
void backtrack(List<Integer> state,int target,int[] choices,int start,List<List<Integer>> res){
//子集和等于target时,记录解
if(target==0){
res.add(new ArrayList<>(state));
return;
}
//遍历所有的选择
//剪枝二:从start开始遍历,避免生成重复子集
for(int i=start;i<choices.length;i++){
if(target-choices[i]<0){
break;
}
//尝试:做出选择,更新target,start
state.add(choices[i]);
backtrack(state,target-choices[i],choices,i,res);
//回退:撤销选择,恢复到之前的状态
state.remove(state.size()-1);
}
}
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<Integer> state =new ArrayList<>();//状态(子集)
Arrays.sort(candidates);
int start=0;//遍历起始点
List<List<Integer>> res =new ArrayList<>();
backtrack(state,target,candidates,start,res);
return res;
}
}
3.缺失第一个正数
首先我们先用几个简单的例子来演示一下:
第一个例子是 1 2 -1 4 5,第一个不满足要求的元素就是-1,对应下标就是 2,先用肉眼看看,我们在 1 2 -1 4 5情况下,没有出现的最小的正整数很明显是 3。尝试着找规律——
满足要求,那么要求是什么呢?
我们需要找到:第一个不满足要求的元素下标
匹配成功的条件也就是数组的 元素值=元素下标+1
swap(当前位置元素<---->目的位置元素)
目的位置: nums[i] - 1
也就是 值为4的元素 要放到下标为 3 的位置
class Solution {
public int firstMissingPositive(int[] nums) {
int len =nums.length;
for(int i =0;i<lenli++){
while(nums[i]>0&&nums[i]<=len&&nums[nums[i]-1]!=nums[i]){
//满足在指定范围内,并没有放在正确的位置上,才交换
//例如数组3应该放在索引2的位置上
swap(nums,nums[i]-1,i);
}
}
for(int i =0;i<len;i++){
if(nums[i]!=i+1){
return i+1;
}
}
//都正确则返回数组长度+1
return len+1;
}
peivate void swap(int[] nums,int index1, int index2){
int temp =nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
}
}
}