1. 冒泡排序实现及复杂度
算法思想:每次比较相邻的两个元素,一直到数组末尾,这样一组操作每次会确定最大位置的元素;重复操作每次将剩下元素中较大的元素交换到数组后面,直到所有元素都确定好位置。
复杂度分析:平均O(n^n),最好O(n),最坏O(n^2)。
稳定性:稳定。
代码模板:
class Solution {
public void bubbleSort(int[] nums) {
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums.length - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
swap(nums, j, j + 1);
}
}
}
}
private void swap(int[] nums, int p, int q) {
int tmp = nums[p];
nums[p] = nums[q];
nums[q] = tmp;
}
}
2. 归并排序实现及复杂度
归并排序的思想详解
自己之前总结的各种排序
算法思想: 先拆分再合并。
复杂度分析:平均O(nlogn),最好O(nlogn),最坏O(nlogn)。
稳定性:稳定。
代码模板:
class Solution {
public void mergeSort(int[] nums, int start, int end) {
if(start<end){
int mid = (start + end) / 2;
mergeSort(nums, start, mid);
mergeSort(nums, mid + 1, end);
merge(nums, start, mid, end);
}
}
private void merge(int[] nums, int start, int mid, int end) {
int p1 = start;
int p2 = mid + 1;
int index = start;
int[] tmp = new int[nums.length];
while (p1 <= mid && p2 <= end) {
if (nums[p1] < nums[p2]) {
tmp[index++] = nums[p1++];
} else {
tmp[index++] = nums[p2++];
}
}
while (p1 <= mid) {
tmp[index++] = nums[p1];
}
while (p2 <= end) {
tmp[index++] = nums[p2++];
}
for (int i = start; i <= end; i++) {
nums[i] = tmp[i];
}
}
}
3,快速排序实现及复杂度
快速排序的思想
快速排序会问到的问题
自己之前总结的各种排序
算法思想:采用了分治法和递归思想。首先找一个元素作为哨兵,再将大于它和小于它的分别放在右边和左边,这就确定了哨兵的位置。再依次排哨兵左边和右边的数组。
复杂度分析:平均O(nlogn),最好O(nlogn),最坏O(n^2)。
稳定性:不稳定。
代码模板:
class Solution {
public void quickSort(int[] nums, int low, int high) {
int p1 = low;
int p2 = high;
if (low < high) {
int tmp = nums[low];
while (p1 < p2) {
while (p1 < p2 && nums[p2] > tmp) {
p2--;
}
if (p1 < p2) {
nums[p1] = nums[p2];
p1++;
}
while (p1 < p2 && nums[p1] < tmp) {
p1++;
}
if (p1 < p2) {
nums[p2] = nums[p1];
p2--;
}
}
nums[p1] = tmp;
quickSort(nums, low, p1 - 1);
quickSort(nums, p1 + 1, high);
} else {
return;
}
}
}
TopK
这题直接应用快速排序模板先排序,再去前k个值。
但是力扣上有在快速排序上效率更高的思想,只排到前k个就行了,不用排之后的。
import java.util.Arrays;
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
quickSort(arr,0,arr.length-1);
return Arrays.copyOf(arr,k);
}
private void quickSort(int[] nums, int low, int high) {
int p1 = low;
int p2 = high;
if (low < high) {
int tmp = nums[low];
while (p1 < p2) {
while (p1 < p2 && nums[p2] > tmp) {
p2--;
}
if (p1 < p2) {
nums[p1] = nums[p2];
p1++;
}
while (p1 < p2 && nums[p1] < tmp) {
p1++;
}
if (p1 < p2) {
nums[p2] = nums[p1];
p2--;
}
}
nums[p1] = tmp;
quickSort(nums, low, p1 - 1);
quickSort(nums, p1 + 1, high);
} else {
return;
}
}
}
4.动态规划
5.回溯法
import java.util.*;
class Solution {
/**
* 全排列
*
* @param nums
* @return
*/
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
boolean[] used = new boolean[nums.length];
backtrack(nums, ans, 0, path, used);
return ans;
}
/**
* 回溯法
*
* @param nums
* @param ans
* @param i
* @param path
* @param used
* @return
*/
private void backtrack(int[] nums, List<List<Integer>> ans, int depth, LinkedList<Integer> path, boolean[] used) {
if (depth == nums.length) {
ans.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (used[i]) {
continue;
}
path.addLast(nums[i]);
used[i] = true;
backtrack(nums, ans, depth + 1, path, used);
path.removeLast();
used[i] = false;
}
}
}
class Solution {
private int count = 0;
public int findTargetSumWays(int[] nums, int S) {
backtrack(nums, S, 0);
return count;
}
/**
* 回溯法
* @param nums
* @param rest
* @param i
*/
private void backtrack(int[] nums, int rest, int i) {
if (i == nums.length) {
if (rest == 0) {
count++;
}
return;
}
rest -= nums[i];
backtrack(nums, rest, i + 1);
rest += nums[i];
rest += nums[i];
backtrack(nums, rest, i + 1);
rest -= nums[i];
}
}
import java.util.*;
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> sub = new LinkedList<>();
Arrays.sort(candidates);
backtrack(candidates, target, 0, ans, sub);
return ans;
}
/**
* 回溯法&剪枝
* @param candidates
* @param rest
* @param i
* @param ans
* @param sub
*/
private void backtrack(int[] candidates, int rest, int i, List<List<Integer>> ans, LinkedList<Integer> sub) {
if (rest == 0) {
ans.add(new LinkedList<>(sub));
return;
}
for (int k = i; k < candidates.length; k++) {
if (rest - candidates[k] < 0) {
break;
}
sub.add(candidates[k]);
backtrack(candidates, rest - candidates[k], k, ans, sub);
sub.removeLast();
}
}
}
组合总和 II(允许不同级不允许同级那里没看太懂)
import java.util.*;
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> sub = new LinkedList<>();
Arrays.sort(candidates);
backtrack(candidates, target, 0, ans, sub);
return ans;
}
/**
* 回溯法&剪枝
*
* @param candidates
* @param rest
* @param i
* @param ans
* @param sub
*/
private void backtrack(int[] candidates, int rest, int i, List<List<Integer>> ans, LinkedList<Integer> sub) {
if (rest == 0) {
ans.add(new LinkedList<>(sub));
return;
}
for (int k = i; k < candidates.length; k++) {
if (rest - candidates[k] < 0) {
break;
}
//允许不同级但不允许同级
if (k > i && candidates[k] == candidates[k - 1]) {
continue;
}
//加上当前的数
sub.add(candidates[k]);
backtrack(candidates, rest - candidates[k], k + 1, ans, sub);
sub.removeLast();
}
}
}
全排列 II(同样是同级不同级那里)
import java.util.*;
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> sub = new LinkedList<>();
boolean[] used=new boolean[nums.length];
Arrays.sort(nums);
backtrack(nums, used,0, ans, sub);
return ans;
}
/**
* 回溯法&剪枝
* @param nums
* @param used
* @param i
* @param ans
* @param sub
*/
private void backtrack(int[] nums, boolean[] used, int i, List<List<Integer>> ans, LinkedList<Integer> sub) {
if (sub.size() == nums.length) {
ans.add(new LinkedList<>(sub));
return;
}
for (int k = 0; k < nums.length; k++) {
if(used[k]){
continue;
}
//允许不同级但不允许同级
if (k > 0 && nums[k] == nums[k - 1]&&used[k-1]) {
continue;
}
//加上当前的数
sub.add(nums[k]);
used[k]=true;
backtrack(nums, used, k + 1, ans, sub);
used[k]=false;
sub.removeLast();
}
}
}
import java.util.*;
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans=new ArrayList<>();
LinkedList<Integer> sub=new LinkedList<>();
backtrack(nums,ans,sub,0);
return ans;
}
private void backtrack(int[] nums, List<List<Integer>> ans, LinkedList<Integer> sub, int i) {
if(i==nums.length){
ans.add(new LinkedList<>(sub));
return;
}
sub.addLast(nums[i]);
backtrack(nums,ans,sub,i+1);
sub.removeLast();
backtrack(nums,ans,sub,i+1);
}
}
import java.util.*;
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> sub = new LinkedList<>();
Arrays.sort(nums);
backtrack(nums, ans, sub, 0);
return ans;
}
private void backtrack(int[] nums, List<List<Integer>> ans, LinkedList<Integer> sub, int i) {
ans.add(new LinkedList<>(sub));
for (int k = i; k < nums.length; k++) {
if (k > i && nums[k] == nums[k - 1]) {
continue;
}
sub.addLast(nums[k]);
backtrack(nums, ans, sub, k + 1);
sub.removeLast();
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。