数组
对撞指针
快慢指针,滑动窗口
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int left = 0,right = -1;
int sum = 0;
int len = nums.length;
int minLen = len + 1;
while(left < len){
if(sum < target && right+1 < len){//小则右加
sum+=nums[++right];
}else{//大则左加
sum-=nums[left++];
}
if(sum >= target){
minLen = Math.min(right-left+1,minLen);//保存最小的
}
}
if(minLen == len+1){
return 0;
}
return minLen;
}
}
哈希集合
class MyHashSet {
private final int MAX_LEN = 100000; // the amount of buckets
private List<Integer>[] set; // hash set implemented by array
/** Returns the corresponding bucket index. */
private int getIndex(int key) {
return key % MAX_LEN;
}
/** Search the key in a specific bucket. Returns -1 if the key does not existed. */
private int getPos(int key, int index) {
// Each bucket contains a list.
List<Integer> temp = set[index];
if (temp == null) {
return -1;
}
// Iterate all the elements in the bucket to find the target key.
for (int i = 0; i < temp.size(); ++i) {
if (temp.get(i) == key) {
return i;
}
}
return -1;
}
/** Initialize your data structure here. */
public MyHashSet() {
set = (List<Integer>[])new ArrayList[MAX_LEN];
}
public void add(int key) {
int index = getIndex(key);
int pos = getPos(key, index);
if (pos < 0) {
// Add new key if key does not exist.
if (set[index] == null) {
set[index] = new ArrayList<Integer>();
}
set[index].add(key);
}
}
public void remove(int key) {
int index = getIndex(key);
int pos = getPos(key, index);
if (pos >= 0) {
// Remove the key if key exists.
set[index].remove(pos);
}
}
/** Returns true if this set did not already contain the specified element */
public boolean contains(int key) {
int index = getIndex(key);
int pos = getPos(key, index);
return pos >= 0;
}
}
/**
* Your MyHashSet object will be instantiated and called as such:
* MyHashSet obj = new MyHashSet();
* obj.add(key);
* obj.remove(key);
* boolean param_3 = obj.contains(key);
*/
哈希表设计
import javafx.util.Pair;
class MyHashMap {
private final int MAX_LEN = 100000; // the amount of buckets
private List<Pair<Integer, Integer>>[] map; // hash map implemented by array
/** Returns the corresponding bucket index. */
private int getIndex(int key) {
return key % MAX_LEN;
}
/** Search the key in a specific bucket. Returns -1 if the key does not existed. */
private int getPos(int key, int index) {
// Each bucket contains a list.
List<Pair<Integer, Integer>> temp = map[index];
if (temp == null) {
return -1;
}
// Iterate all the elements in the bucket to find the target key.
for (int i = 0; i < temp.size(); ++i) {
if (temp.get(i).getKey() == key) {
return i;
}
}
return -1;
}
/** Initialize your data structure here. */
public MyHashMap() {
map = (List<Pair<Integer, Integer>>[])new ArrayList[MAX_LEN];
}
/** value will always be positive. */
public void put(int key, int value) {
int index = getIndex(key);
int pos = getPos(key, index);
if (pos < 0) {
// Add new (key, value) pair if key is not existed.
if (map[index] == null) {
map[index] = new ArrayList<Pair<Integer, Integer>>();
}
map[index].add(new Pair(key, value));
} else {
// Update the value if key is existed.
map[index].set(pos, new Pair(key, value));
}
}
/** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
public int get(int key) {
int index = getIndex(key);
int pos = getPos(key, index);
if (pos < 0) {
return -1;
} else {
return map[index].get(pos).getValue();
}
}
/** Removes the mapping of the specified value key if this map contains a mapping for the key */
public void remove(int key) {
int index = getIndex(key);
int pos = getPos(key, index);
if (pos >= 0) {
map[index].remove(pos);
}
}
}
/**
* Your MyHashMap object will be instantiated and called as such:
* MyHashMap obj = new MyHashMap();
* obj.put(key,value);
* int param_2 = obj.get(key);
* obj.remove(key);
*/
哈希表设计键
class Solution {
public int romanToInt(String s) {
Map<String, Integer> map = new HashMap<>();
map.put("I", 1);
map.put("IV", 4);
map.put("V", 5);
map.put("IX", 9);
map.put("X", 10);
map.put("XL", 40);
map.put("L", 50);
map.put("XC", 90);
map.put("C", 100);
map.put("CD", 400);
map.put("D", 500);
map.put("CM", 900);
map.put("M", 1000);
int ans = 0;
for(int i = 0;i < s.length();) {
if(i + 1 < s.length() && map.containsKey(s.substring(i, i+2))) {
ans += map.get(s.substring(i, i+2));
i += 2;
} else {
ans += map.get(s.substring(i, i+1));
i ++;
}
}
return ans;
}
}
动态规划原理
线性动态规划
普通单串问题
带维度单串问题
双串问题
矩阵问题
前缀和
数据结构维护前缀和
前缀积前缀异或推广
区间动态规划
背包动态规划
状态压缩动态规划
计数问题
矩阵快速幂和数位问题
深度优先
数据结构栈
深度优先应用
回溯算法
剪枝算法
二维平面上的搜索问题
动态规划和深度优先遍历结合
排序算法
贪心算法
广度优先
二维平面上的搜索问题:广度
抽象成图
拓扑排序
双向BFS和多源BFS
二叉树的遍历
二叉树用递归解决问题
private int answer; // don't forget to initialize answer before call maximum_depth
private void maximum_depth(TreeNode root, int depth) {
if (root == null) {
return;
}
if (root.left == null && root.right == null) {
answer = Math.max(answer, depth);
}
maximum_depth(root.left, depth + 1);
maximum_depth(root.right, depth + 1);
}
public int maximum_depth(TreeNode root) {
if (root == null) {
return 0; // return 0 for null node
}
int left_depth = maximum_depth(root.left);
int right_depth = maximum_depth(root.right);
return Math.max(left_depth, right_depth) + 1; // return depth of the subtree rooted at root
}
n叉树
二分查找模板
模板1
int binarySearch(int[] nums, int target){
if(nums == null || nums.length == 0)
return -1;
int left = 0, right = nums.length - 1;
while(left <= right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid - 1; }
}
// End Condition: left > right
return -1;
}
二分查找模板2
int binarySearch(int[] nums, int target){
if(nums == null || nums.length == 0)
return -1;
int left = 0, right = nums.length;
while(left < right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if(nums[mid] == target){ return mid; }
else if(nums[mid] < target) { left = mid + 1; }
else { right = mid; }
}
// Post-processing:
// End Condition: left == right
if(left != nums.length && nums[left] == target) return left;
return -1;
}
class Solution {
public int findPeakElement(int[] nums) {
int l=0;
int r=nums.length-1;
while(l<r){
int mid=(l+r)/2;
if(nums[mid]>nums[mid+1]){
r=mid;
}
else{
l=mid+1;
}
}
return l;
}
}
class Solution {
public int findMin(int[] nums) {
int n=nums.length;
int l=0,r=n-1;
while(l<r){
int mid=l+(r-l)/2;
if(nums[mid]<=nums[n-1]){
r=mid;
}
else{
l=mid+1;
}
}
return nums[l];
}
}
二分查找模板3
int binarySearch(int[] nums, int target) {
if (nums == null || nums.length == 0)
return -1;
int left = 0, right = nums.length - 1;
while (left + 1 < right){
// Prevent (left + right) overflow
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid;
} else {
right = mid;
}
}
// Post-processing:
// End Condition: left + 1 == right
if(nums[left] == target) return left;
if(nums[right] == target) return right;
return -1;
}
二分查找模板分析
数据库
位运算
队列
// "static void main" must be defined in a public class.
class MyQueue {
// store elements
private List<Integer> data;
// a pointer to indicate the start position
private int p_start;
public MyQueue() {
data = new ArrayList<Integer>();
p_start = 0;
}
/** Insert an element into the queue. Return true if the operation is successful. */
public boolean enQueue(int x) {
data.add(x);
return true;
};
/** Delete an element from the queue. Return true if the operation is successful. */
public boolean deQueue() {
if (isEmpty() == true) {
return false;
}
p_start++;
return true;
}
/** Get the front item from the queue. */
public int Front() {
return data.get(p_start);
}
/** Checks whether the queue is empty or not. */
public boolean isEmpty() {
return p_start >= data.size();
}
};
public class Main {
public static void main(String[] args) {
MyQueue q = new MyQueue();
q.enQueue(5);
q.enQueue(3);
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
q.deQueue();
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
q.deQueue();
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
}
}
class MyCircularQueue {
private int[] data;
private int head;
private int tail;
private int size;
/** Initialize your data structure here. Set the size of the queue to be k. */
public MyCircularQueue(int k) {
data = new int[k];
head = -1;
tail = -1;
size = k;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
public boolean enQueue(int value) {
if (isFull() == true) {
return false;
}
if (isEmpty() == true) {
head = 0;
}
tail = (tail + 1) % size;
data[tail] = value;
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
public boolean deQueue() {
if (isEmpty() == true) {
return false;
}
if (head == tail) {
head = -1;
tail = -1;
return true;
}
head = (head + 1) % size;
return true;
}
/** Get the front item from the queue. */
public int Front() {
if (isEmpty() == true) {
return -1;
}
return data[head];
}
/** Get the last item from the queue. */
public int Rear() {
if (isEmpty() == true) {
return -1;
}
return data[tail];
}
/** Checks whether the circular queue is empty or not. */
public boolean isEmpty() {
return head == -1;
}
/** Checks whether the circular queue is full or not. */
public boolean isFull() {
return ((tail + 1) % size) == head;
}
}
/**
* Your MyCircularQueue object will be instantiated and called as such:
* MyCircularQueue obj = new MyCircularQueue(k);
* boolean param_1 = obj.enQueue(value);
* boolean param_2 = obj.deQueue();
* int param_3 = obj.Front();
* int param_4 = obj.Rear();
* boolean param_5 = obj.isEmpty();
* boolean param_6 = obj.isFull();
*/
队列广度优先
/**
* Return the length of the shortest path between root and target node.
*/
int BFS(Node root, Node target) {
Queue<Node> queue; // store all nodes which are waiting to be processed
int step = 0; // number of steps neeeded from root to current node
// initialize
add root to queue;
// BFS
while (queue is not empty) {
step = step + 1;
// iterate the nodes which are already in the queue
int size = queue.size();
for (int i = 0; i < size; ++i) {
Node cur = the first node in queue;
return step if cur is target;
for (Node next : the neighbors of cur) {
add next to queue;
}
remove the first node from queue;
}
}
return -1; // there is no path from root to target
}
栈
// "static void main" must be defined in a public class.
public class Main {
public static void main(String[] args) {
// 1. Initialize a stack.
Stack<Integer> s = new Stack<>();
// 2. Push new element.
s.push(5);
s.push(13);
s.push(8);
s.push(6);
// 3. Check if stack is empty.
if (s.empty() == true) {
System.out.println("Stack is empty!");
return;
}
// 4. Pop an element.
s.pop();
// 5. Get the top element.
System.out.println("The top element is: " + s.peek());
// 6. Get the size of the stack.
System.out.println("The size is: " + s.size());
}
}
栈和深度优先遍历
/*
* Return true if there is a path from cur to target.
*/
boolean DFS(Node cur, Node target, Set<Node> visited) {
return true if cur is target;
for (next : each neighbor of cur) {
if (next is not in visited) {
add next to visted;
return true if DFS(next, target, visited) == true;
}
}
return false;
}