【LeetCode】算法模板与刷题方法小结(不断更新中)

一、代码模板

1、递归

// Java
public void recur(int level, int param) {
    
     

  // terminator 
  if (level > MAX_LEVEL) {
    
     
    // process result 
    return; 
  }

  // process current logic 
  process(level, param); 

  // drill down 
  recur( level: level + 1, newParam); 

  // restore current status 

2、分治

private static int divide_conquer(Problem problem) {
    
    
  // terminator 
  if (problem == NULL) {
    
    
    int res = process_last_result();
    return res;     
  }
  
  // process current logic:split the big problems
  subProblems = split_problem(problem)
  
  // drill down:conquer subproblems, merge subresults
  res0 = divide_conquer(subProblems[0])
  res1 = divide_conquer(subProblems[1])
  result = process_result(res0, res1);

  // revert the current level states
  
  return result;
}

3、BFS

public class TreeNode {
    
    
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
    
    
        val = x;
    }
}

public List<List<Integer>> levelOrder(TreeNode root) {
    
    

	List<List<Integer>> allResults = new ArrayList<>();
    if (root == null)  return allResults;
    
    Queue<TreeNode> nodes = new LinkedList<>();
    nodes.add(root);
    while (!nodes.isEmpty()) {
    
    
        int levelSize = nodes.size();
        List<Integer> results = new ArrayList<>();
        for (int i = 0; i < levelSize; i++) {
    
    
            TreeNode currNode = nodes.poll();
            results.add(currNode.val);
            if (currNode.left != null)  nodes.add(currNode.left);
            if (currNode.right != null)  nodes.add(currNode.right);
        }
        allResults.add(results);
    }
    return allResults;
}

More:双向BFS
……

4、DFS

4.1 递归

DFS模板:

voidDFS ( Vertex V ) 
{
    
    
	visited[V] = true;  
	for( V 的每个邻接点W )
		if( !visited[W] )
	DFS( W );
}
public List<List<Integer>> levelOrder(TreeNode root) {
    
    
 	
	if(root==null)  return allResults;
	List<List<Integer>> allResults = new ArrayList<>();
	travel(root, 0, allResults);
	return allResults;
}


private void travel(TreeNode root, int level, List<List<Integer>> results){
    
    
    // process current node here. 
    if(results.size()==level)  results.add(new ArrayList<>());
    results.get(level).add(root.val);
    
    if(root.left!=null)  travel(root.left, level+1, results);
    if(root.right!=null)  travel(root.right, level+1, results);
}

4.2 迭代(非递归写法)

void dfs(TreeNode root) {
    
    

	if(root!=null) return ;
	
	Set<Integer> visited = new HashSet<>();
	stack<TreeNode> stackNode;
	stackNode.push(root);
	
	while (!stackNode.isEmpty()) {
    
    
		TreeNode node = stackNode.pop();
		if(visited.contains(node.val))  continue;  // already visited 
		visited.add(node.val);
		
		for (int i = node.children.length() - 1; i >= 0; --i) {
    
    
			stackNode.push(node.children[i]);
		}
	}

	return ;
}

5、二分

// java
public int binarySearch(int[] array, int target) {
    
    
    int left = 0, right = array.length - 1, mid;
    while (left <= right) {
    
    
        mid = (right - left) / 2 + left;
        if (array[mid] == target) {
    
    
            return mid;
        } else if (array[mid] > target) {
    
    
            right = mid - 1;
        } else {
    
    
            left = mid + 1;
        }
    }
    return -1;
}

6、二叉树

层序遍历模板可参考上面的BFS。

7、并查集

class UnionFind {
    
    
    private int count = 0;
    private int[] father;
    public UnionFind(int n) {
    
    
        count = n;
        father = new int[n];
        for (int i = 0; i < n; i++) {
    
    
            father[i] = i;
        }
    }
    public int find(int p) {
    
    
        while (p != father[p]) {
    
    
            father[p] = father[father[p]];
            p = father[p];
        }
        return p;
    }
    public void union(int p, int q) {
    
    
        int rootP = find(p);
        int rootQ = find(q);
        if (rootP != rootQ) {
    
    
	        father[rootP] = rootQ;
	        count--;
        }
    }
}

More

// find() 第二个版本,合并的较为彻底
private int find(int p) {
    
    
	int root = p;
	while (root != father[p]) {
    
    
		root = father[p];
	}
	while (p != father[p]) {
    
    
		int tmp = father[p];
		father[p] = root;
		p = tmp;
	}
	return root;
}

// find() 第三个版本:递归
public int find (int p) {
    
    
     if (father[p] == p) {
    
    
         return p;
     }
     father[p] = find(father[p]);
     return father[p];
 }

public boolean connected(int p, int q) {
    
    
	return find(p)==find(q);
}

//  union() 版本2:细化+优化
public UnionFind(int n) {
    
    
    count = n;
    father = new int[n];
    rank = new int[n];
    for (int i = 0; i < n; i++) {
    
    
        father[i] = i;
        rank[i] = 0;
    }
}

public Union(int p, int q) {
    
    
    int rootP = find(p);
    int rootQ = find(q);
    if (rootP == rootQ) return;
    if (rank[rootP]<rank[rootQ]) father[rootP] = rootQ;
    else if (rank[rootP]>rank[rootQ]) father[rootQ] = rootP;
    else {
    
     father[rootP] = rootQ; rank[rootQ]++; }
    count--;
}

8、排序

1、快排
快排

public static void quickSort(int[] array, int begin, int end) {
    
    
    if (end <= begin) return;
    int pivot = partition(array, begin, end);
    quickSort(array, begin, pivot - 1);
    quickSort(array, pivot + 1, end);
}

static int partition(int[] a, int begin, int end) {
    
    
    // pivot: 标杆位置,counter: 小于pivot的元素的个数
    int pivot = end, counter = begin;  
    for (int i = begin; i < end; i++) {
    
    
        if (a[i] < a[pivot]) {
    
    
            int temp = a[counter]; a[counter] = a[i]; a[i] = temp;
            counter++;
        }
    }
    int temp = a[pivot]; a[pivot] = a[counter]; a[counter] = temp;
    return counter;
}

2、归并
归并

public static void mergeSort(int[] array, int left, int right) {
    
    

	if (right <= left) return;
	if mid = (left + right) >> 1; // (left+right)/2
	
	mergeSort(array, left, mid);
	mergeSort(array, mid+1, right);
	merge(array, left, mid, right);
}

public static void merge(int[] arr, int left, int mid, int right) {
    
    
	
	int[] temp = new int[right-left+1];  // 中间数组
	int i = left, j = mid+1, k = 0;
	
	while (i<=mid && j<=right) {
    
    
		temp[k++] = arr[i]<=arr[j] ? arr[i++] : arr[j++];
	}
	while (i<=mid)   temp[k++] = arr[i++];
	while (j<=right) temp[k++] = arr[j++];
	
	for (int p=0; p<temp.length; p++) {
    
    
		arr[left+p] = temp[p];
	}
	// 也可以用 System.arraycopy(a, start1, b, start2, length)
}

3、堆排序
堆排序

版本1–PriorityQueue():

void heapSort(int[] arr) {
    
    
	
	int len = arr.length;
	PriorityQueue<Integer> q = new PriorityQueue<>();

	for (int i=0; i<len; i++) {
    
    
		q.add(a[i]);
	}
	
	for (int i=0; i<len; i++) {
    
    
		a[i] = q.pop();
	}
}

版本2–手动实现:

static void heapify(int[] array, int length, int i) {
    
    
	int left = 2*i+1, right=2*i+2;
	int largest = i;
	
	if (left<length && array[left]>array[largest]) {
    
    
		largest = leftChild;
	}
	if (right<length && array[right]>array[largest]) {
    
    
		largest = right;
	}
	
	if (largest != i) {
    
    
		int temp = array; array[i] = array[largest]; array[largest] = temp;
		heapify[array, length, largest);
	}
}

public static void heapSort(int[] array) {
    
    
	if (array.length == 0) return;
	int length = array.length;
	for (int i = length/2-1; i>=0; i--) {
    
    
		heapify(array, length, i);
	}
	
	for (int i=length-1; i>=0; i--) {
    
    
		int temp = array[0]; array[0] = array[i]; array = temp;
		heapify(array, i, 0);
	}
}

9、动态规划

二、刷题方法

三、参考

1、递归代码模板
2、分治代码模板
3、BFS 代码模板
4、DFS 代码模板(递归写法、非递归写法)
5、二分查找代码模板

猜你喜欢

转载自blog.csdn.net/HeavenDan/article/details/108533614