基础算法学习
1.双指针
双指针思想:一个数组,设定左右指针,left 和 right,左指针指向数组第一项,右指针指向数组最后一项。相加得出一个和sum,与target值相比较。根据比较的结果,对left和right进行移动。但需注意的是,使用双指针,数组得是有序的,如果数组无序,需要先是使用Arrays.sort()进行排序。
j
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int closeSum = nums[0]+nums[1]+nums[2];
for(int i=0;i<nums.length-2;i++){
int left = i+1;
int right =nums.length-1;
while(left<right){
int sum2 = nums[i] + nums[left]+nums[right];
if(Math.abs(target-sum2)<Math.abs(target-closeSum)){
closeSum = sum2;
}
if(sum2>target){
right--;
}else if(target>sum2){
left++;
}else{
return target;
}
}
}
return closeSum;
}
}
j
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
for(int i=0;i<nums.length-3;i++){
if(i>0&&nums[i] == nums[i-1]) continue;
for(int j =i+1;j<nums.length-2;j++){
if(j>i+1&&nums[j] == nums[j-1]) continue;
int left = j+1;
int right = nums.length -1;
while(left<right){
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if(sum == target){
res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}else if(sum > target){
right--;
}else{
left++;
}
}
}
}
return res;
}
}
j
class Solution {
public int triangleNumber(int[] nums) {
Arrays.sort(nums);
int n = nums.length-1;
int sum = 0;
for(int i =n;i>1;i--){
int left = 0;
int right = i-1;
while(left<right){
if(nums[left] +nums[right]>nums[i]){
sum += right- left;
right--;
}else{
left++;
}
}
}
return sum;
}
}
二分查找
二分查找原理就是通过将left+right的中间值与target进行比较,然后移动左右指针,来缩小未检索范围。
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
j
class Solution {
public int[] searchRange(int[] nums, int target) {
int start = lowerBound(nums,target)
if( start == nums.length || nums[start] != target){
return new int[]{-1,-1}
}
int end = lowerBound(nums,target+1)-1
return new int[]{start,end}
}
}
private int lowerBound( int[] nums,int target){
int left = 0;
int right = nums.length()-1;
while(left<=right){
int mid = left + (right - left) / 2;
if(nums[mid] >= target){
right = mid-1;
} else {
left = mid + 1;
}
}
return left
}
java
class Solution {
public int findPeakElement(int[] nums) {
int left = 0;
int right = nums.length-2;
while(left<=right){
int mid = left + (right-left) / 2;
if(nums[mid] > nums[mid+1]){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
}
dfs
全排列
java
class Solution {
private int[] nums;
private boolean[] onPath;
private List<Integer> path;
private final List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
this.nums = nums;
path = Arrays.asList(new Integer[nums.length]);
onPath = new boolean[nums.length];
dfs(0);
return ans;
}
private void dfs(int i){
if(i == nums.length){
ans.add(new ArrayList<>(path));
return;
}
for(int j =0;j<nums.length;++j){
if(!onPath[j]){
path.set(i,nums[j]);
onPath[j] = true;
dfs(i+1);
onPath[j] = false;
}
}
}
}
N皇后
java
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> ans = new ArrayList<>();
int [] queens = new int[n];
boolean [] col = new boolean[n];
boolean [] diag1 = new boolean[n*2-1];
boolean [] diag2 = new boolean[n*2-1];
dfs(0,queens,col,diag1,diag2,ans);
return ans;
}
private static void dfs(int r,int[] queens,boolean [] col,boolean[] diag1,boolean[] diag2,List<List<String>> ans){
int n = col.length;
if(r == n){
List<String> board = new ArrayList<>();
for(int c :queens){
char [] row = new char[n];
Arrays.fill(row,'.');
row[c] = 'Q';
board.add(new String(row));
}
ans.add(board);
return;
}
for(int c=0;c<n;c++){
int rc = r-c+n-1;
if(!col[c]&&!diag1[r+c]&&!diag2[rc]){
queens[r] =c;
col[c] = diag1[r+c] = diag2[rc] = true;
dfs(r+1,queens,col,diag1,diag2,ans);
col[c] = diag1[r+c] = diag2[rc] = false;
}
}
}
}