public class TopK_Partition {
public static List<Integer> topK(int[] a, int k){
List<Integer> res = new LinkedList<>();
int begin = 0, end = a.length-1;
int index = partition(a, begin, end);
while (index != k-1){
if(index > k-1){
end = index-1;
index = partition(a, begin, end);
}else{
begin = index+1;
index = partition(a, begin, end);
}
}
for (int i = 0; i <= index; i++) {
res.add(a[i]);
}
return res;
}
private static int partition(int[] a, int left, int right){
if(left >= right) return left;
int low = left, high = right;
int pivot = a[left];
while (low < high){
while (low < high && a[high] > pivot){
high--;
}
a[low] = a[high];
while (low < high && a[low] < pivot){
low++;
}
a[high] = a[low];
}
a[low] = pivot;
return low;
}
public static void main(String[] args) {
int[] a = {9,8,7,6,5,4,3,2,1,0};
int k = 4;
System.out.println(topK(a, k));
}
}
public class TopK {
public static List<Integer> getTopK(int[] a, int k){
PriorityQueue<Integer> pq = new PriorityQueue<>(
(o1, o2) -> o1- o2
//(o1,o2) -> o2-o1
);
List<Integer> res = new LinkedList<>();
for(int item: a){
if(pq.size() < k){
pq.add(item);
}else {
if(pq.peek() < item){
pq.poll();
pq.add(item);
}
}
}
while (!pq.isEmpty()){
res.add(pq.poll());
}
return res;
}
public static void main(String[] args) {
int[] a = {1,2,3,4,5,6,7,8};
int k = 3;
System.out.println(getTopK(a, k));
}
}
public class strToInt {
public static int strToInt(String str){
if(str == null || str.length() == 0) return 0;
boolean isNegative = false;
int i = 0;
long res = 0;
while (i < str.length() && str.charAt(i) == ' ') i++;
if(i == str.length()) return (int)res;
if(str.charAt(i) != '-' && str.charAt(i) != '+' && !Character.isDigit(str.charAt(i))) {
return 0;
}
if(str.charAt(i) == '-' || str.charAt(i) == '+'){
if(str.charAt(i) == '-'){
isNegative = true;
}
i++;
}
while (i < str.length()){
if(!Character.isDigit(str.charAt(i))){
return (int) (isNegative ? -res : res);
}else{
res = res * 10 + str.charAt(i) - '0';
long temp_res = isNegative ? -res : res;
if(temp_res <= Integer.MIN_VALUE) return Integer.MIN_VALUE;
if(temp_res >= Integer.MAX_VALUE) return Integer.MAX_VALUE;
}
i++;
}
return (int) (isNegative ? -res : res);
}
public static void main(String[] args) {
System.out.println(strToInt("-91283472332"));
}
}
public class QuickSort {
public static void quickSort(int[] a, int left, int right){
if(left >= right) return;
int low = left, high = right;
int pivot = a[low];
while (low < high){
while (low < high && a[high] > pivot){
high--;
}
a[low] = a[high];
while (low < high && a[low] < pivot){
low++;
}
a[high] = a[low];
}
a[low] = pivot;
quickSort(a, left, low-1);
quickSort(a, low+1, right);
}
public static void main(String[] args) {
int[] a = {9,8,7,6,5,4,3,2,1,0};
quickSort(a, 0, a.length-1);
System.out.println(Arrays.toString(a));
}
}
public class numIslands {
public static int numIslands(char[][] grid){
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if(grid[i][j] == '1' ){
dfs(grid, i, j);
res++;
}
}
}
return res;
}
private static void dfs(char[][] grid, int i, int j){
if(i < 0 || i >= grid.length || j < 0 ||
j >= grid[i].length || grid[i][j] != '1'){
return;
}
grid[i][j] = '2';
dfs(grid, i-1, j);
dfs(grid, i+1, j);
dfs(grid, i, j-1);
dfs(grid, i, j+1);
}
}
public class LongestUndupString {
public static int getlongest(String s){
char[] ss = s.toCharArray();
int res = 0;
int left = 0, right = 0;
int[] window = new int[256];
while (right < ss.length){
char c = ss[right];
right++;
window[c]++;
while (window[c] > 1){
char d = ss[left];
left++;
window[d]--;
}
res = Math.max(res, right-left);
}
return res;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String str = scanner.nextLine();
System.out.println(getlongest(str));
}
}
public class Lee567_CheckInclusion {
public boolean checkInclusion(String s, String t){
char[] ss = s.toCharArray();
char[] ts = t.toCharArray();
int[] window = new int[256];
for(char c : ts) window[c]++;
int left = 0, right = 0;
int match = ts.length;
while (right < ss.length){
char c = ss[right];
if(window[c] > 0) match--;
window[c]--;
right++;
while (match == 0){
if(right - left == ts.length){
return true;
}
char d = ss[left];
if(window[d] == 0) match++;
window[d]++;
left++;
}
}
return false;
}
public static void main(String[] args) {
String s = "eidbaooo", t = "ab";
System.out.println(new Lee567_CheckInclusion().checkInclusion(s,t));
}
}
快排
public static void quickSort(int[] a, int left, int right){
int low = left, high = right;
if(low >= high) return;
int pivot = a[low];
while (low < high){
while(low < high && a[high] >= pivot){
high--;
}
a[low] = a[high];
while(low < high && a[low] <= pivot){
low++;
}
a[high] = a[low];
}
a[low] = pivot;
quickSort(a, left, low-1);
quickSort(a, low+1, right);
}
归并
//数组归并
public static void mergeSort(int[] a,int left, int right){
if(left >= right) return; //递归出口
int mid = (left + right) >> 1;
mergeSort(a, left, mid);
mergeSort(a, mid+1, right);
merge(a, left, mid, right);
}
private static void merge(int[] a, int left, int mid, int right) {
int lindex = left, rindex = mid+1; //lindex赋值为left
int[] temp = new int[right-left+1];
int tempIndex = 0;
while(lindex <= mid && rindex <= right){
if(a[lindex] <= a[rindex]){
temp[tempIndex++] = a[lindex++];
}else{
temp[tempIndex++] = a[rindex++];
}
}
while(lindex <= mid){ //while循环
temp[tempIndex++] = a[lindex++];
}
while(rindex <= right){
temp[tempIndex++] = a[rindex++];
}
for(int i = 0; i < tempIndex; i ++){
a[left+i] = temp[i];
}
}
//链表归并
public static ListNode mergeList(ListNode head){
if(head == null || head.next == null)
return head;
ListNode midNode = getMidNode(head);
ListNode rightHead = midNode.next;
midNode.next = null;
ListNode newLeftHead = mergeList(head);
ListNode newRighthead = mergeList(rightHead);
return merge(newLeftHead, newRighthead);
}
private static ListNode merge(ListNode newLeftHead, ListNode newRighthead) {
ListNode dummyHead = new ListNode(-1);
ListNode curLeft = newLeftHead, curRight = newRighthead;
ListNode curNew = dummyHead;
while (curLeft != null && curRight != null){
if(curLeft.val <= curRight.val){
curNew.next = curLeft;
curLeft = curLeft.next;
}else{
curNew.next = curRight;
curRight = curRight.next;
}
curNew = curNew.next;
}
curNew.next = curLeft == null ? curRight : curLeft;
return dummyHead.next;
}
private static ListNode getMidNode(ListNode head) {
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode fast = dummyHead, slow = dummyHead;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
冒泡
public static void bubbleSort(int[] a){
for(int i = a.length-1; i >= 0; i --){
for(int j = 0; j < i; j ++){
if(a[j] > a[j+1] ){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
堆排
package sortAlgo;
import java.util.Arrays;
public class HeapSort_prac {
public void heapSort(int[] a){
if(a == null || a.length < 1){
return;
}
buildMaxHeap(a);
for (int i = a.length-1; i >= 0; i --) {
swap(a, 0, i);
maxHeapify(a, i, 0);
}
}
private void maxHeapify(int[] a, int size, int index) {
int leftChild = 2 * index + 1;
int rightChild = 2 * index + 2;
int largest = index;
if(leftChild < size && a[leftChild] > a[largest]){
largest = leftChild;
}
if(rightChild < size && a[rightChild] > a[largest]){
largest = rightChild;
}
if(largest != index){
swap(a, largest, index);
maxHeapify(a, size, largest);
}
}
private void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
private void buildMaxHeap(int[] a) {
for(int i = (a.length-1) / 2; i >= 0; i --){
maxHeapify(a, a.length, i);
}
}
public static void main(String[] args) {
int[] a = {9,8,7,6,5,4,3,2,1,0};
new HeapSort_prac().heapSort(a);
System.out.println(Arrays.toString(a));
}
}
TopK
package offer;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.PriorityQueue;
public class TopK {
public List<Integer> topK(int[] nums, int k){
/*PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
//return o1-o2; 最小堆 求最大的k个数
//return o2-o1; 最大堆 求最小的k个数
return o1-o2;
}
});*/
PriorityQueue<Integer> pq = new PriorityQueue<>(
(o1, o2) -> o1 - o2
);
for(int i : nums){
if(pq.size() < k){
pq.add(i);
}else{
if(i > pq.peek()){
pq.remove();
pq.add(i);
}
}
}
List<Integer> res = new LinkedList<>();
while (!pq.isEmpty()){
res.add(pq.remove());
}
return res;
}
public static void main(String[] args) {
int[] nums = {1,2,3,4,5,6};
int k = 2;
List<Integer> res = new TopK().topK(nums, k);
System.out.println(res.toString());
}
}
树的遍历
public class TravelBinaryTree {
//中序遍历
//递归版本
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>();
recur(root, res);
return res;
}
private void recur(TreeNode root, List<Integer> res) {
if(root == null) return;
recur(root.left, res);
res.add(root.val);
recur(root.right, res);
}
//迭代版本
public List<Integer> inorderTraversal1(TreeNode root) {
List<Integer> res = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode curNode = root;
while (curNode != null || !stack.isEmpty()){
while(curNode != null){
stack.push(curNode);
curNode = curNode.left;
}
curNode = stack.pop();
res.add(curNode.val);
curNode = curNode.right;
}
return res;
}
//前序遍历
//递归版本
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new LinkedList<>();
recur_pre(root, res);
return res;
}
private void recur_pre(TreeNode root, List<Integer> res) {
if(root == null) return;
res.add(root.val);
recur_pre(root.left, res);
recur_pre(root.right, res);
}
//迭代版本
public List<Integer> preorderTraversal1(TreeNode root) {
List<Integer> res = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode curNode = root;
while(curNode != null || !stack.isEmpty()){
while(curNode != null){
res.add(curNode.val);
stack.push(curNode);
curNode = curNode.left;
}
curNode = stack.pop();
curNode = curNode.right;
}
return res;
}
//后序遍历
//递归版本
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> res = new LinkedList<>();
recur_post(root, res);
return res;
}
private void recur_post(TreeNode root, List<Integer> res) {
if(root == null) return;
recur_post(root.left, res);
recur_post(root.right,res);
res.add(root.val);
}
//迭代版本
public List<Integer> postorderTraversal1(TreeNode root) {
List<Integer> res = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
TreeNode curNode = root;
while (curNode != null || !stack.isEmpty()){
while (curNode != null){
stack.push(curNode);
stack.push(curNode);
curNode = curNode.left;
}
curNode = stack.pop();
if(!stack.isEmpty() && curNode == stack.peek()){
curNode = curNode.right;
}else{
res.add(curNode.val);
curNode = null;
}
}
return res;
}
}
BFS
树的层序遍历(I)
public int[] levelOrder(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
List<Integer> res = new LinkedList<>();
if (root != null)
q.offer(root);
while (!q.isEmpty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode curNode = q.poll();
res.add(curNode.val);
if (curNode.left != null) {
q.offer(curNode.left);
}
if (curNode.right != null) {
q.offer(curNode.right);
}
}
}
return res.stream().mapToInt(Integer::valueOf).toArray();
树的层序遍历(II)
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
List<Integer> curLevel = new LinkedList<>();
Queue<TreeNode> q = new LinkedList<>();
if(root != null){
q.offer(root);
}
while(!q.isEmpty()){
int size = q.size();
curLevel.clear();
for(int i = 0; i < size; i ++){
TreeNode cur = q.poll();
curLevel.add(cur.val);
if(cur.left != null){
q.offer(cur.left);
}
if(cur.right != null){
q.offer(cur.right);
}
}
res.add(new LinkedList<>(curLevel));
}
return res;
}
树的层序遍历(III)–之字打印二叉树
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new LinkedList<>();
List<Integer> curLevel = new LinkedList<>();
int levelNum = 1;
Queue<TreeNode> q = new LinkedList<>();
if(root != null)
q.offer(root);
while(!q.isEmpty()){
int size = q.size();
curLevel.clear();
for (int i = 0; i < size; i++) {
TreeNode curNode = q.poll();
curLevel.add(curNode.val);
if(curNode.left != null){
q.offer(curNode.left);
}
if(curNode.right != null){
q.offer(curNode.right);
}
}
if(levelNum % 2 == 0){
Collections.reverse(curLevel);
}
res.add(new LinkedList<>(curLevel));
levelNum++;
}
return res;
}
二叉树的右视图、左视图、边界节点
public List<Integer> rightSideView(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
List<Integer> res = new LinkedList<>();
if(root != null)
q.offer(root);
while (!q.isEmpty()){
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode curNode = q.poll();
//加入时机 右视图
if(i == size-1){
res.add(curNode.val);
}
//左视图
/*if(i == 0){
res.add(curNode.val);
}*/
//边界节点
/*if(i == 0 || i == size -1){
res.add(curNode.val);
}*/
if(curNode.left != null)
q.offer(curNode.left);
if(curNode.right != null)
q.offer(curNode.right);
}
}
return res;
}
二叉树的深度
从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。
public int maxDepth(TreeNode root) {
if(root == null)
return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
二叉树的直径
int maxd = 0;
public int diameterOfBinaryTree(TreeNode root) {
depth(root);
return maxd;
}
private int depth(TreeNode root) {
if(root == null) return 0;
int leftDepth = depth(root.left);
int rightDepth = depth(root.right);
maxd = Math.max(maxd, leftDepth + rightDepth);
return Math.max(leftDepth, rightDepth) + 1;
}
二叉树的最小高度
//dfs
public int minDepth(TreeNode root) {
if(root == null)
return 0;
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
if(root.left == null || root.right == null)
return leftDepth+rightDepth+1;
return Math.min(leftDepth,rightDepth) + 1;
}
//bfs
public int minDepth2(TreeNode root){
Queue<TreeNode> q = new LinkedList<>();
if(root == null) return 0;
q.offer(root);
int levelNum = 1;
while(!q.isEmpty()){
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode curNode = q.poll();
if(curNode.left == null && curNode.right == null){
return levelNum;
}
if(curNode.left != null)
q.offer(curNode.left);
if(curNode.right != null)
q.offer(curNode.right);
}
levelNum++;
}
return levelNum;
}
判断是否为平衡二叉树
//递归
public int treeDepth(TreeNode root){
if(root == null)
return 0;
int leftDepth = treeDepth(root.left);
int rightDepth = treeDepth(root.right);
return Math.max(leftDepth, rightDepth) + 1;
}
public boolean isBalanced(TreeNode root) {
if(root == null)
return true;
int leftDepth = treeDepth(root.left);
int rightDepth = treeDepth(root.right);
if(Math.abs(leftDepth - rightDepth) > 1)
return false;
return isBalanced(root.left) && isBalanced(root.right);
}
//非递归
public boolean isBalanced2(TreeNode root){
return recur(root) != -1;
}
private int recur(TreeNode root){
if(root == null) return 0;
int left = recur(root.left);
if(left == -1) return -1;
int right = recur(root.right);
if(right == -1) return -1;
return Math.abs(left-right) < 2 ? Math.max(left,right) + 1 : -1;
}
查找链表的中间结点
public ListNode middleNode(ListNode head) {
//找的是偶数中间偏右的结点(可以加个假头用来得到中间偏左的结点)
ListNode fast = head, slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
判断链表是否有环并获取环入口
public ListNode detectCycle(ListNode head) {
ListNode fast = head, slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow) {
slow = head;
while(slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
}
找出两个单链表相交结点
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode curA = headA, curB = headB;
while(curA != curB) {
curA = curA == null ? headB : curA.next;
curB = curB == null ? headA : curB.next;
}
return curA;
}
用链表模拟整数相加
public static ListNode addTwoList(ListNode l1, ListNode l2){
ListNode dummyHead = new ListNode(-1);
ListNode cur1 = l1, cur2 = l2, curRes = dummyHead;
int carry = 0;
while(cur1 != null || cur2 != null || carry != 0){
int first = cur1 == null ? 0 : cur1.val;
int second = cur2 == null ? 0 : cur2.val;;
int sum = first + second + carry;
int bit = sum % 10;
carry = sum / 10;
curRes.next = new ListNode(bit);
curRes = curRes.next;
if(cur1 != null) cur1 = cur1.next;
if(cur2 != null) cur2 = cur2.next;
}
return dummyHead.next;
}
链表逆序
//逆序[a,b)区间的链表 当b=null时,相当于整个链表逆序
public static ListNode reserve(ListNode a, ListNode b){
ListNode pre, cur, next;
pre = null; cur = a;
while(cur != b){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
K个一组翻转链表
public static ListNode reserveK(ListNode head, int k){
ListNode a, b;
a = b = head;
for (int i = 0; i < k; i++) {
if(b == null) return a;
b = b.next;
}
ListNode newHead = reserve(a, b);
a.next = reserveK(b, k);
return newHead;
}
public static ListNode reserve(ListNode a, ListNode b){
ListNode pre, cur, next;
pre = null; cur = a;
while(cur != b){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
单链表的归并排序
//先“拆”后“分”的思想,这里与数组的归并排序可以类比记忆
public static void mergeSort(int[] a,int left, int right){
if(left >= right) return; //递归出口
int mid = (left + right) >> 1;
mergeSort(a, left, mid);
mergeSort(a, mid+1, right);
merge(a, left, mid, right);
}
private static void merge(int[] a, int left, int mid, int right) {
int lindex = left, rindex = mid+1; //lindex赋值为left
int[] temp = new int[right-left+1];
int tempIndex = 0;
while(lindex <= mid && rindex <= right){
if(a[lindex] <= a[rindex]){
temp[tempIndex++] = a[lindex++];
}else{
temp[tempIndex++] = a[rindex++];
}
}
while(lindex <= mid){ //while循环
temp[tempIndex++] = a[lindex++];
}
while(rindex <= right){
temp[tempIndex++] = a[rindex++];
}
for(int i = 0; i < tempIndex; i ++){
a[left+i] = temp[i];
}
}
LRU
package leetcode;
import java.util.HashMap;
public class LRUCache {
//双向链表 (内部类)
class Node{
int key;
int value;
Node pre;
Node next;
public Node(int key, int value) {
this.key = key;
this.value = value;
this.pre = null;
this.next = null;
}
}
//初始容量,map + 双向链表
public int capacity;
public HashMap<Integer, Node> map;
public Node head;
public Node tail;
public LRUCache(int capacity){
this.capacity = capacity;
map = new HashMap<>();
head = new Node(-1,-1);
tail = new Node(-1,-1);
head.next = tail;
tail.pre = head;
}
//get: 先在map中查找是否包含key值,找不到直接返回-1
//找到则取出Node结点,删将其移到尾部(删除该结点,并添加到尾部)
public int get(int key){
if(!map.containsKey(key)){
return -1;
}
Node cur = map.get(key);
cur.pre.next = cur.next;
cur.next.pre = cur.pre;
moveToTail(cur);
return cur.value;
}
//将该Node结点添加到链表尾
private void moveToTail(Node cur) {
//移到链表尾
cur.pre = tail.pre;
cur.next = tail;
cur.pre.next = cur;
tail.pre = cur;
}
//如果map中包含该结点,则直接修改对应的value值。
//否则创建结点加入map中,并加入到双向链表末尾
//之后若链表长度超过容量,则删除头结点,并删除map中对应的key值
public void put(int key, int value){
if(get(key) != -1){
map.get(key).value = value;
return;
}
Node cur = new Node(key, value);
map.put(cur.key, cur);
moveToTail(cur);
if(map.size() > capacity){
//删除头结点
map.remove(head.next.key);
head.next = head.next.next;
head.next.pre = head;
}
}
//打印 观察结点
public void print(Node head){
Node cur = head.next;
while (cur != tail){
System.out.print("(" + cur.key + "," + cur.value +")");
cur = cur.next;
}
System.out.println();
}
public static void main(String[] args) {
LRUCache lruCache = new LRUCache(2);
lruCache.put(1,1); lruCache.print(lruCache.head);
lruCache.put(2,2); lruCache.print(lruCache.head);
System.out.print(lruCache.get(1)); lruCache.print(lruCache.head);
lruCache.put(3,3); lruCache.print(lruCache.head);
lruCache.put(2,5); lruCache.print(lruCache.head);
System.out.println(lruCache.get(5));
lruCache.put(4,4); lruCache.print(lruCache.head);
}
}
数组全排列
public class Off38_Permute {
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> permute(int[] a){
List<Integer> trace = new LinkedList<>();
traceback(a, trace);
return res;
}
private void traceback(int[] a, List<Integer> trace){
if(trace.size() == a.length){
res.add(new LinkedList<>(trace));
return;
}
for (int i = 0; i < a.length; i++) {
if(trace.contains(a[i])){
continue;
}
trace.add(a[i]);
traceback(a, trace);
trace.remove(trace.size()-1);
}
}
}
括号生成
public class Off22_GenerateParenthesis {
List<String> res = new LinkedList<>();
public List<String> generateParenthesis(int n){
StringBuffer trace = new StringBuffer();
traceback(n, trace,0,0);
return res;
}
private void traceback(int n, StringBuffer trace, int left, int right) {
if(left < right) return;
if(left > n || right > n) return;
if(trace.length() == n * 2){
res.add(trace.toString());
return;
}
trace.append('(');
traceback(n, trace, left+1, right);
trace.deleteCharAt(trace.length()-1);
trace.append(')');
traceback(n, trace, left, right+1);
trace.deleteCharAt(trace.length()-1);
}
}
N皇后
public class Lee51_NQueen {
List<List<String>> res = new LinkedList<>();
public List<List<String>> nQueen(int n){
char[][] board = new char[n][n];
for(char[] chars : board){
Arrays.fill(chars, '.');
}
traceback(board, 0);
return res;
}
private void traceback(char[][] board, int row) {
if(row == board.length) {
res.add(charToString(board));
return;
}
for(int col = 0; col < board[row].length; col ++){
if(isValid(board, row, col)){
board[row][col] = 'Q';
traceback(board, row+1);
board[row][col] = '.';
}
}
}
private boolean isValid(char[][] board, int row, int col) {
for(int i = 0; i < row; i ++){
if(board[i][col] == 'Q'){
return false;
}
}
for(int i = row-1, j = col -1; i >= 0 && j >= 0; i--,j--){
if(board[i][j] == 'Q'){
return false;
}
}
for(int i = row-1, j = col + 1; i >= 0 && j < board[i].length; i--,j++){
if(board[i][j] == 'Q'){
return false;
}
}
return true;
}
private List<String> charToString(char[][] board) {
List<String> ans = new LinkedList<>();
for(char[] chars : board){
ans.add(String.valueOf(chars));
}
return ans;
}
public static void main(String[] args) {
List<List<String>> res = new Lee51_NQueen().nQueen(4);
for(List<String> list : res)
System.out.println(list);
}
}
组合总数
public class Lee39_CombaneSum {
List<List<Integer>> res = new LinkedList<>();
public List<List<Integer>> combaneSum(int[] a, int target){
List<Integer> trace = new LinkedList<>();
Arrays.sort(a);
traceback(a, target, trace);
return res;
}
private void traceback(int[] a, int target, List<Integer> trace) {
int sum = 0;
for(int item : trace)
sum += item;
if(sum >= target){
if(sum == target)
res.add(new LinkedList<>(trace));
return;
}
for (int i = 0; i < a.length; i++) {
if(trace.size() > 0 && a[i] < trace.get(trace.size()-1)){
continue;
}
trace.add(a[i]);
traceback(a, target, trace);
trace.remove(trace.size()-1);
}
}
}
最长无重复字符串
public String longestUnDupSubString(String s){
char[] charArray = s.toCharArray();
int[] window = new int[256];
int left = 0, right = 0;
int len = 0, start = 0;
while (right < charArray.length){
char c = charArray[right];
window[c]++;
right++;
while (window[c] > 1){
char d = charArray[left];
window[d]--;
left++;
}
if(right-left > len){
len = right-left;
start = left;
}
}
return s.substring(start, start+len);
}
最长公共子序列
最长回文子串
public String longestPalindrome(String s) {
//中心点扩展法
String res = new String();
for (int i = 0; i < s.length(); i++) {
String res1 = helper(s, i, i);
String res2 = helper(s, i, i + 1);
res = res.length() > res1.length() ? res : res1;
res = res.length() > res2.length() ? res : res2;
}
return res;
}
private String helper(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return s.substring(left + 1, right);
}
最长回文子序列长度
public int dpSolution(String s){
char[] ss = s.toCharArray();
int len = ss.length;
int[][] dp = new int[len][len];
for(int i = 0; i < dp.length; i ++){
dp[i][i] = 1;
}
for(int i = dp.length-1; i >=0; i --){
for(int j = i+1; j < dp[i].length; j++){
if(ss[i] == ss[j]){
dp[i][j] = dp[i+1][j-1] + 2;
}else {
dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][len-1];
}
LCS最长公共子序列
//最长公共子序列
//if (s[i] = s[j] ) dp[i][j] = dp[i-1][j-1]+1
//else dp[i][j] = max(dp[i][j-1], dp[i-1][j])
public int LCS(String s, String t){
int rows = s.length();
int cols = t.length();
int[][] dp = new int[rows+1][cols+1];
for(int i = 1; i <= rows; i ++){
for(int j = 1; j <= cols; j ++){
if(s.charAt(i-1) == t.charAt(j-1)){
dp[i][j] = dp[i-1][j-1]+1;
}else{
dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
}
}
}
return dp[rows][cols];
}
LIS(I) 最长递增子序列的长度
public int LIS(int[] nums){
int maxLen = 0;
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
for(int i = 0; i < nums.length; i ++){
for(int j = 0; j < i; j ++){
if(nums[j] < nums[i]){
dp[i] = Math.max(dp[j]+1, dp[i]);
}
}
maxLen = Math.max(maxLen, dp[i]);
}
return maxLen;
}
LIS(II) 最长递增子序列长度的个数
public int lengthOfLIS(int[] nums){
int maxLen = 0;
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
int[] count = new int[nums.length];
Arrays.fill(count, 1);
for(int i = 0; i < nums.length; i ++){
for(int j = 0; j < i; j ++){
if(nums[j] < nums[i]){
if(dp[j]+1 > dp[i]){
dp[i] = dp[j]+1;
count[i] = count[j];
}else if(dp[j]+1 == dp[i]){
count[i] += count[j];
}
}
}
maxLen = Math.max(maxLen, dp[i]);
}
int res = 0;
for(int i = 0; i < nums.length; i ++){
if(dp[i] == maxLen){
res += count[i];
}
}
return res;
}
LIS(III) 最长连续递增子序列
//dp
public int lengthOfLIS(int[] nums){
int maxLen = 0;
int[] dp = new int[nums.length];
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
if( i > 0 && nums[i] > nums[i-1]){
dp[i] = Math.max(dp[i-1]+1, dp[i]);
}
maxLen = Math.max(maxLen, dp[i]);
}
return maxLen;
}
//双指针
public int lengthOfLIS2(int[] nums){
if(nums == null || nums.length == 0) return 0;
int maxLen = 1;
int left = 0, right = 1, len = 1;
while(right < nums.length){
if(nums[right] > nums[right-1]){
len++;
maxLen = Math.max(maxLen, len);
}else{
len = 1;
left = right;
}
right++;
}
return maxLen;
}
买卖股票的最佳时间
public int maxProfit(int[] nums){
int hisMinValue = Integer.MAX_VALUE;
int maxProfit = 0;
for (int i = 0; i < nums.length; i++) {
//记录历史最低值
hisMinValue = Math.min(hisMinValue, nums[i]);
//当天卖出能获得的最大利润(当天值-历史最低值),去更新总的最大利润
maxProfit = Math.max(maxProfit, nums[i] - hisMinValue);
}
return maxProfit;
}
零钱兑换
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount+1];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int i = 0; i <= amount; i ++){
for(int coin : coins){
if(i-coin < 0 || dp[i-coin] == Integer.MAX_VALUE) continue;
dp[i] = Math.min(dp[i-coin] + 1, dp[i]);
}
}
return dp[amount] == Integer.MAX_VALUE ? -1 : dp[amount];
}
两个数只出现一次,其余数出现两次,找出这两个数
public int[] singleNumbers(int[] nums) {
int[] res = new int[2];
int sum = 0;
for(int i : nums){
sum ^= i;
}
int lowbit = sum & -sum;
for(int i : nums){
if((lowbit & i) == 0){
res[0] ^= i;
}else{
res[1] ^= i;
}
}
return res;
}
一个数出现一次,其余出现三次,找出这一个数
public int singleNumber(int[] nums){
int[] bitSum = new int[32];
for(int num : nums){
int bitMask = 1;
for(int i = 31; i >= 0; i --){
if((bitMask & num) != 0) bitSum[i]++;
bitMask <<= 1;
}
}
int res = 0;
for(int i = 0; i < 32; i ++){
res <<= 1;
res += bitSum[i] % 3;
}
return res;
}