4月7日
计算逆序对
import java.util.*;
public class AntiOrder {
public int count(int[] A, int n) {
// write code here
if (A == null || n == 0) return 0;
return mergeSortRecursion(A, 0, n-1);
}
public int mergeSortRecursion(int[] a, int l, int r) {
if (l == r) return 0;
int m = l + (r-l) / 2;
//逆序对 = 前半部分逆序对 + 后半部分逆序对 + 整体的逆序对
return mergeSortRecursion(a, l, m) + mergeSortRecursion(a, m+1, r) + merge(a, l, m, r);
}
public int merge(int[] a, int l, int m, int r) {
int[] tmp = new int[r-l+1];
//i 前部分起始下标 j后部分起始下标 k临时数组的下标
int i = l, j = m+1, k = 0;
int res = 0;
//注意等号
while (i <= m && j <= r) {
if (a[i] <= a[j]) {
tmp[k++] = a[i++];
}else {
//关键代码 2个排序数组, 如果一个数组第一个数比第二个数组的第一个数大 则逆序对个数 = m-i+1;
res += m-i+1;
tmp[k++] = a[j++];
}
}
//处理剩余元素
while (i <= m) tmp[k++] = a[i++];
while (j <= r) tmp[k++] = a[j++];
for (int x = 0; x < tmp.length; x++) {
a[l++] = tmp[x];
}
return res;
}
}
最小调整有序
给定一个int数组A和数组的大小n,请返回一个二元组,代表所求序列的起点和终点。(原序列位置从0开始标号,若原序列有序,返回[0,0])。保证A中元素均为正整数。
import java.util.*;
public class Rearrange {
public int[] findSegment(int[] a, int len) {
// write code here
int[] res = new int[2];
if (a == null) return res;
int m = 0, n = 0;
//找出比当前元素之前最大元素小的元素就是n
int max = a[0];
for (int i = 1; i < len; i++) {
//注意等号
if (a[i] >= max) {
max = a[i];
}else {
n = i;
}
}
//找出比当前元素之后最小元素大的元素就是m
int min = a[len-1];
for (int i = len-2; i >= 0; i--) {
if (a[i] <= min) {
min = a[i];
}else {
m = i;
}
}
res[0] = m;
res[1] = n;
return res;
}
}
最大连续数列和
import java.util.*;
public class MaxSum {
public int getMaxSum(int[] a, int n) {
int[] dp = new int[n];
//注意默认值是a[0]
int res = a[0];
dp[0] = a[0];
for (int i = 1; i < n; i++) {
dp[i] = Math.max(dp[i-1]+a[i], a[i]);
res = Math.max(res, dp[i]);
}
return res;
}
}
4月8日
整数对查找
import java.util.*;
public class FindPair {
public int countPairs(int[] a, int n, int sum) {
// write code here
int res = 0;
HashMap<Integer, Integer> wordCount = new HashMap();
for (int i = 0; i < n; i++) {
//查询余数元素个数 然后相加
Integer count = wordCount.get(sum-a[i]);
Integer tmp = wordCount.get(a[i]);
res += (count == null) ? 0 : count;
//统计每个元素个数
wordCount.put(a[i], (tmp == null ? 0 : tmp) +1);
}
return res;
}
}
树转链表
import java.util.*;
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}*/
public class Converter {
public ListNode treeToList(TreeNode root) {
// write code here
Stack<TreeNode> stack = new Stack();
ListNode res = new ListNode(-1);
ListNode pre = res;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
pre.next = new ListNode(root.val);
pre = pre.next;
root = root.right;
}
return res.next;
}
}
下一个较大元素
import java.util.*;
public class NextElement {
public int[] findNext(int[] a, int n) {
// write code here
//使用栈倒序遍历, 将元素放入栈中
Stack<Integer> stack = new Stack<>();
stack.push(-1);
ArrayList<Integer> res = new ArrayList<>();
for(int i = n-1; i >= 0; i--) {
Integer tmp = stack.peek();
//从栈中查找比自己大的元素
while (tmp != null && tmp != -1 && tmp <= a[i]) {
stack.pop();
tmp = stack.peek();
}
//每次插入头部
res.add(0,tmp == null ? -1 : tmp);
stack.push(a[i]);
}
return res.stream().mapToInt(i -> Integer.valueOf(i)).toArray();
}
}
下一个较大元素中最小的元素
public static int[] findNext(int[] A, int n) {
// write code here
if(n <= 0)
return null;
Stack<Integer> stack1 = new Stack<>();
Stack<Integer> stack2 = new Stack<>();
int[] result = new int[n];
for(int i = n -1; i >= 0; i--){
//将比当前元素小的元素放入辅助栈
while(!stack1.empty() && stack1.peek() <= A[i]) {
stack2.push(stack1.pop());
}
//取出比当前元素大的最小的元素
result[i] = stack1.empty()? -1 : stack1.peek();
//将当前元素放入主栈 实现主栈有序
stack1.push(A[i]);
//将比当前元素小的元素放入主栈
while(!stack2.empty()){
stack1.push(stack2.pop());
}
}
return result;
}
插入排序动态获得中位数
public static int[] getMiddle(int[] A, int n) {
// write code here
int[]res=new int[A.length];
res[0]=A[0];
//插入排序, 每次取i/2的数
for (int i = 1; i < A.length; i++) {
int k=i-1;
int tem=A[i];
//比当前元素大的数后移
while(k>=0&&A[k]>tem){
A[k+1]=A[k];
k--;
}
//将当前元素插入
A[++k]=tem;
res[i]=A[i/2];
}
return res;
}
最大子方阵
import java.util.*;
public class SubMatrix {
public int maxSubMatrix(int[][] mat, int n) {
// write code here
int maxLen = n;
//从大到小
while (maxLen > 0) {
for (int i = 0; i <= n-maxLen; i++) {
for (int j = 0; j <= n-maxLen; j++) {
//基础颜色
int base = mat[i][j];
boolean flag = true;
for (int k = 0; k < maxLen; k++) {
//上下左右列
int top = mat[i][j+k];
int bottom = mat[i+maxLen-1][j+k];
int left = mat[i+k][j];
int right = mat[i+k][j+maxLen-1];
if (top != base || bottom != base || left != base || right != base) {
flag = false;
break;
}
}
if (flag) return maxLen;
}
}
maxLen--;
}
return 0;
}
}
最大和子矩阵
import java.util.*;
public class SubMatrix {
public int sumOfSubMatrix(int[][] mat, int n) {
// write code here
int res = Integer.MIN_VALUE;
for (int i = 0 ;i < n; i++) {
int[] tmp = mat[i];
//计算每一行的最大连续序列和
res = Math.max(res, help(tmp));
//接下来的i+1行
for (int j = i+1; j < n; j++) {
//每行的每个元素
for (int k = 0; k < n; k++) {
tmp[k] += mat[j][k];
}
res = Math.max(res, help(tmp));
}
}
return res;
}
//计算最大连续累加和
private int help(int[] a) {
int sum = a[0];
int res = a[0];
for (int i = 1; i < a.length; i++) {
sum = Math.max(sum+a[i], a[i]);
res = Math.max(res, sum);
}
return res;
}
}