目录
c.用数组实现队列(常考题)(循环数组,用一个size巧妙解决问题)
一.三种算法
1.选择排序、冒泡排序、插入排序(对数器验证)
package class1;
import java.util.Arrays;
public class SelectionSort {
//选择排序
public static void SelectionSort(int[] arr) {
if(arr==null ||arr.length<2) {
return;
}
for(int i=0;i<arr.length-1;i++)
{
int minindex=i;
for(int j=i+1;j<arr.length;j++) {
minindex=arr[j]<arr[minindex]?j:minindex;
}
swap(arr,minindex,i);
}
}
//冒泡排序
public static void bubuleSort(int[] arr) {
if(arr==null ||arr.length<2) {
return;
}
for(int e=arr.length-1;e>0;e--) {
for(int i=0;i<e;i++) {
if(arr[i]>arr[i+1]) {
swap(arr,i,i+1);
}
}
}
}
//插入排序
public static void insertSort(int[] arr) {
if(arr==null || arr.length<2) {
return;
}
for(int i=1;i<arr.length;i++) {
for(int j=i-1;j>=0 && arr[j]>arr[j+1];j--) {
swap(arr,j,j+1);
}
}
}
public static void swap(int[] arr,int i,int j) {
int t=arr[i];
arr[i]=arr[j];
arr[j]=t;
}
public static void comparator(int[] arr) {
Arrays.sort(arr);
}
public static int[] generateRandomArray(int maxSize,int maxValue) {
//Math.random() -->[0,1);
//Math.random()*N -->[0,N);
//(int)Math.random()*N --->[0,N-1];
int arr[]=new int[(int)((maxSize+1)*Math.random())];
for(int i=0;i<arr.length;i++) {
//产生[-N,N]的整数
arr[i]=(int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
public static int[] copyarray(int[] arr) {
if(arr==null) {
return null;
}
int[] res=new int[arr.length];
for(int i=0;i<arr.length;i++) {
res[i]=arr[i];
}
return res;
}
public static boolean isEqual(int[] arr,int[] res) {
if((arr==null&&res!=null)||(arr!=null&&res==null) ) {
return false;
}
if(arr.length!=res.length){
return false;
}
if(arr==null&&res==null) {
return true;
}
for(int i=0;i<arr.length;i++) {
if(arr[i]!=res[i]) {
return false;
}
}
return true;
}
public static void printArray(int[] arr) {
if(arr==null) {
return;
}
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int maxSize=100;
int maxValue=100;
int testtime=500000;
boolean succeed=true;
for(int i=0;i<testtime;i++) {
int[] arr1=generateRandomArray(maxSize,maxValue);
int[] arr2=copyarray(arr1);
//bubuleSort(arr1);
insertSort(arr1);
comparator(arr2);
if(!isEqual(arr1,arr2)) {
succeed=false;
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(succeed?"Nice!":"Fucking fucked!");
int arr[]=generateRandomArray(maxSize,maxValue);
printArray(arr);
insertSort(arr);
printArray(arr);
}
}
二、二分查找
1.查找特定值
package class1;
import java.util.Arrays;
public class BSExist {
public static boolean exist (int[] sortArray,int num) {
if(sortArray==null || sortArray.length==0) {
return false;
}
int l=0;
int r=sortArray.length-1;
int mid=0;
while(l<=r) {
mid=l+((r-l)>>1);
if(sortArray[mid]==num) {
return true;
}
if(sortArray[mid]>num) {
r=mid-1;
}
if(sortArray[mid]<num) {
l=mid+1;
}
}
//return sortArray[l] == num;这种情况是while的条件l<r
return false;//这种情况是while的条件l<=r
}
public static boolean test(int[] sortArray,int num) {
for(int cur:sortArray) {
if(cur==num) {
return true;
}
}
return false;
}
public static void printArray(int[] arr) {
if(arr==null) {
return;
}
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
public static void main(String[] args) {
int maxSize=10;
int maxValue=100;
int testtime=500000;
boolean succeed=true;
for(int i=0;i<testtime;i++) {
int arr[]=generateRandomArray(maxSize, maxValue);
Arrays.sort(arr);
int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
if(exist(arr,value)!=test(arr,value)) {
succeed=false;
printArray(arr);
System.out.println(value);
break;
}
}
System.out.println(succeed?"Nice!":"Fucking fucked!");
}
}
2.二分查找的应用(局部最小,时间复杂度logN)
public static int getLessindex(int[] arr) {
if(arr==null || arr.length==0) {
return -1;
}
if(arr.length==1 || arr[0]<arr[1]) {
return 0;
}
if(arr[arr.length-2]>arr[arr.length-1]) {
return arr.length-1;
}
int l=1;
int r=arr.length-2;
int mid=0;
while(l<r) {
mid=(l+r)>>1;
if(arr[mid]>arr[mid-1]) {
r=mid-1;
}
else if(arr[mid]>arr[mid+1]) {
l=mid+1;
}else {
return mid;
}
}
return l;
}
三、异或运算的应用
a.异或(无进位相加)
0^N=N, N^N=0;
b.把int的最有的一位1取出来
N&((~N)+1) 也可以等价于 N&(-N);
c.去掉二进制中的一个1
r=N&((~N)+1)
N^=r;
d.应用(见代码)
package class1;
public class EvenTimesOddTimes {
//一个数组中一个数出现奇数次,其余出现偶数次,找出那个出现奇数次的数
public static void printOddTimesNum1(int[] arr) {
int eor=0;
for(int i=0;i<arr.length;i++) {
eor^=arr[i];
}
System.out.println(eor);
}
//一个数组中两个数出现奇数次,其余出现偶数次,找出那两个出现奇数次的数
public static void printOddTimesNum2(int[] arr) {
int eor=0;
for(int i=0;i<arr.length;i++) {
eor^=arr[i];
}
int rightOne=eor&(-eor);
int onlyOne=0;
for(int i=0;i<arr.length;i++) {
if((arr[i] & rightOne)!=0) {
onlyOne^=arr[i];
}
}
System.out.println(onlyOne+" "+(onlyOne^eor));
}
//数出一个二进制数中有多少个1
public static int bit1counts(int n) {
int count=0;
int rightOne=0;
while(n!=0) {
rightOne=n&(-n);
n^=rightOne;
count++;
}
return count;
}
//使用异或交换两数
public static void swap(int[] arr,int i,int j) {
arr[i]=arr[i]^arr[j];
arr[j]=arr[i]^arr[j];
arr[i]=arr[i]^arr[j];
}
public static void main(String[] args) {
int a=5;
int b=7;
System.out.println(a);
System.out.println(b);
a=a^b;
b=a^b;
a=a^b;
System.out.println(a);
System.out.println(b);
int[] arr1 = { 3, 2, 3, 3, 1, 1, 1, 3, 1, 1, 1 };
printOddTimesNum1(arr1);
swap(arr1,0,1);
System.out.println(arr1[0]+" "+arr1[1]);
int[] arr2 = { 4, 3, 4, 2, 2, 2, 4, 1, 1, 1, 3, 3, 1, 1, 1, 4, 2, 2 };
printOddTimesNum2(arr2);
}
}
异或运算的题目
package class1;
import java.util.HashMap;
import java.util.HashSet;
public class m_KM {
//使用哈希表表,时间复杂度位O(N),空间复杂度位O(N)
public static int test(int[] arr,int k,int m) {
HashMap<Integer,Integer> map=new HashMap<>();
for(int num:arr) {
if(map.containsKey(num)) {
map.put(num, map.get(num)+1);
}else {
map.put(num, 1);
}
}
for(int num:map.keySet()) {
if(map.get(num)==k) {
return num;
}
}
return -1;
}
public static HashMap<Integer,Integer> map=new HashMap<>();
//使用位运算,时间复杂度位O(N),空间复杂度位O(N)
public static int onlyKTimes(int[] arr,int k,int m) {
// if(map.size()==0) {
// mapCreater(map);
// }
int[] t=new int[32];
for(int num:arr) {
for(int i=0;i<32;i++) {
//如果第i位为1,则t[i]++,记录位为1的个数
t[i]+=(num>>i)&1;
}
}
int ans=0;
for(int i=0;i<32;i++) {
//t[i]不能被整除,因为能被整除的一定不是k的数;
if(t[i]%m!=0) {
if(t[i]%m==k) {
//那位为1就或上去
ans |= (1<<i);
}else {
return -1;
}
}
}
//防止一个数出现3,其余出现7次,而0出现5次这种情况
if(ans==0) {
int count=0;
for(int num:arr) {
if(num==0) {
count++;
}
}
if(count!=k) {
return -1;
}
}
return ans;
}
public static void printArray(int[] arr) {
if(arr==null) {
return;
}
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static int[] randomArray(int maxKinds, int range, int k, int m) {
int ktimeNum=randomNumber(range);
int times=Math.random()<0.5?k:((int) (Math.random() * (m - 1)) + 1);
int numKinds=(int)(Math.random()*maxKinds)+2;
int[] arr=new int [times+(numKinds-1)*m];
int index=0;
for(;index<times;index++) {
arr[index]=ktimeNum;
}
numKinds--;
//防止重复加数
HashSet<Integer> set=new HashSet<>();
set.add(ktimeNum);
while(numKinds!=0) {
int curNum=0;
do {
curNum=randomNumber(range);
}while(set.contains(curNum));
set.add(curNum);
numKinds--;
for(int i=0;i<m;i++) {
arr[index++]=curNum;
}
}
for(int i=0;i<arr.length;i++) {
int j=(int)Math.random()*arr.length;
int tmp=arr[i];
arr[i]=arr[j];
arr[j]=tmp;
}
return arr;
}
public static int randomNumber(int range) {
return (int)(Math.random()*range+1)-(int)(Math.random()*range+1);
}
public static void main(String[] args) {
int kinds = 5;
int range = 30;
int testTime = 100000;
int max = 9;
System.out.println("测试开始");
for(int i=0;i<testTime;i++) {
int a=(int)(Math.random()*max+1);
int b=(int)(Math.random()*max+1);
int k=Math.min(a, b);
int m=Math.max(a, b);
if(k==m) {
m++;
}
int[] arr = randomArray(kinds, range, k, m);
int ans1=test(arr,k,m);
int ans2=onlyKTimes(arr,k,m);
if(ans1!=ans2) {
printArray(arr);
System.out.println(ans1);
System.out.println(ans2);
System.out.println("出错了!");
break;
}
}
System.out.println("测试结束");
}
}
四、链表、队列、栈
a.反转链表
package class2;
import java.util.ArrayList;
import java.util.List;
public class list1 {
public static class Node {
public int value;
public Node next;
public Node(int data) {
value = data;
}
}
public static class DoubleNode {
public int value;
public DoubleNode last;
public DoubleNode next;
public DoubleNode(int data) {
value = data;
}
}
// head
// a -> b -> c -> null
// c -> b -> a -> null
public static Node reverseLinkedList(Node head) {
Node pre = null;
Node next = null;
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
public static DoubleNode reverseDoubleList(DoubleNode head) {
DoubleNode pre = null;
DoubleNode next = null;
while (head != null) {
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}
public static Node testReverseLinkedList(Node head) {
if (head == null) {
return null;
}
ArrayList<Node> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
list.get(0).next = null;
int n = list.size();
for (int i = 1; i < n; i++) {
list.get(i).next = list.get(i - 1);
}
return list.get(n - 1);
}
public static DoubleNode testReverseDoubleList(DoubleNode head) {
if (head == null) {
return null;
}
ArrayList<DoubleNode> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
list.get(0).next = null;
DoubleNode pre = list.get(0);
int N = list.size();
for (int i = 1; i < N; i++) {
DoubleNode cur = list.get(i);
cur.last = null;
cur.next = pre;
pre.last = cur;
pre = cur;
}
return list.get(N - 1);
}
// for test
public static Node generateRandomLinkedList(int len, int value) {
int size = (int) (Math.random() * (len + 1));
if (size == 0) {
return null;
}
size--;
Node head = new Node((int) (Math.random() * (value + 1)));
Node pre = head;
while (size != 0) {
Node cur = new Node((int) (Math.random() * (value + 1)));
pre.next = cur;
pre = cur;
size--;
}
return head;
}
// for test
public static DoubleNode generateRandomDoubleList(int len, int value) {
int size = (int) (Math.random() * (len + 1));
if (size == 0) {
return null;
}
size--;
DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1)));
DoubleNode pre = head;
while (size != 0) {
DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1)));
pre.next = cur;
cur.last = pre;
pre = cur;
size--;
}
return head;
}
// for test
public static List<Integer> getLinkedListOriginOrder(Node head) {
List<Integer> ans = new ArrayList<>();
while (head != null) {
ans.add(head.value);
head = head.next;
}
return ans;
}
// for test
public static boolean checkLinkedListReverse(List<Integer> origin, Node head) {
for (int i = origin.size() - 1; i >= 0; i--) {
if (!origin.get(i).equals(head.value)) {
return false;
}
head = head.next;
}
return true;
}
// for test
public static List<Integer> getDoubleListOriginOrder(DoubleNode head) {
List<Integer> ans = new ArrayList<>();
while (head != null) {
ans.add(head.value);
head = head.next;
}
return ans;
}
// for test
public static boolean checkDoubleListReverse(List<Integer> origin, DoubleNode head) {
DoubleNode end = null;
for (int i = origin.size() - 1; i >= 0; i--) {
if (!origin.get(i).equals(head.value)) {
return false;
}
end = head;
head = head.next;
}
for (int i = 0; i < origin.size(); i++) {
if (!origin.get(i).equals(end.value)) {
return false;
}
end = end.last;
}
return true;
}
// for test
public static void main(String[] args) {
int len = 50;
int value = 100;
int testTime = 100000;
System.out.println("test begin!");
for (int i = 0; i < testTime; i++) {
Node node1 = generateRandomLinkedList(len, value);
List<Integer> list1 = getLinkedListOriginOrder(node1);
node1 = reverseLinkedList(node1);
if (!checkLinkedListReverse(list1, node1)) {
System.out.println("Oops1!");
}
Node node2 = generateRandomLinkedList(len, value);
List<Integer> list2 = getLinkedListOriginOrder(node2);
node2 = testReverseLinkedList(node2);
if (!checkLinkedListReverse(list2, node2)) {
System.out.println("Oops2!");
}
DoubleNode node3 = generateRandomDoubleList(len, value);
List<Integer> list3 = getDoubleListOriginOrder(node3);
node3 = reverseDoubleList(node3);
if (!checkDoubleListReverse(list3, node3)) {
System.out.println("Oops3!");
}
DoubleNode node4 = generateRandomDoubleList(len, value);
List<Integer> list4 = getDoubleListOriginOrder(node4);
node4 = reverseDoubleList(node4);
if (!checkDoubleListReverse(list4, node4)) {
System.out.println("Oops4!");
}
}
System.out.println("test finish!");
}
}
b.用链表实现队列和栈
package class2;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class doubleListapp {
public static class Node<T>{
public T value;
public Node<T> last;
public Node<T> next;
public Node(T data) {
value=data;
}
}
public static class DoubleEndQueue<T>{
Node<T> head;
Node<T> tail;
public void addFromHead(T value) {
Node<T> cur=new Node<T>(value);
if(head==null) {
head=cur;
tail=cur;
}else {
cur.next=head;
head.last=cur;
head=cur;
}
}
public void addFromBottom(T value) {
Node<T> cur=new Node<T>(value);
if(head==null) {
head=cur;
tail=cur;
}else {
cur.last=tail;
tail.next=cur;
tail=cur;
}
}
public T popFromHead() {
if(head==null) {
return null;
}
Node<T> cur=head;
if(head==tail) {
head=null;
tail=null;
}else {
head=head.next;
cur.next=null;
head.last=null;
}
return cur.value;
}
public T popFromBottom() {
if(head==null) {
return null;
}
Node<T> cur=tail;
if(head==tail) {
tail=null;
head=null;
}else {
tail=tail.last;
tail.next=null;
cur.last=null;
}
return cur.value;
}
public boolean isEmpty() {
return head==null;
}
}
public static class MyStack<T>{
private DoubleEndQueue<T> queue;
public MyStack() {
queue=new DoubleEndQueue<T>();
}
public void push(T value) {
queue.addFromBottom(value);
}
public T pop() {
return queue.popFromBottom();
}
public boolean isEmpty()
{
return queue.isEmpty();
}
}
public static class MyQueue<T>{
private DoubleEndQueue<T> queue;
public MyQueue(){
queue=new DoubleEndQueue<T>();
}
public void push(T value) {
queue.addFromBottom(value);
}
public T poll(){
return queue.popFromHead();
}
public boolean isEmpty()
{
return queue.isEmpty();
}
}
public static boolean isEqual(Integer o1, Integer o2) {
if (o1 == null && o2 != null) {
return false;
}
if (o1 != null && o2 == null) {
return false;
}
if (o1 == null && o2 == null) {
return true;
}
return o1.equals(o2);
}
public static void main(String[] args) {
int oneTestDataNum = 100;
int value = 10000;
int testTimes = 100000;
for (int i = 0; i < testTimes; i++) {
MyStack<Integer> myStack = new MyStack<>();
MyQueue<Integer> myQueue = new MyQueue<>();
Stack<Integer> stack = new Stack<>();
Queue<Integer> queue = new LinkedList<>();
for (int j = 0; j < oneTestDataNum; j++) {
int nums = (int) (Math.random() * value);
if (stack.isEmpty()) {
myStack.push(nums);
stack.push(nums);
} else {
if (Math.random() < 0.5) {
myStack.push(nums);
stack.push(nums);
} else {
if (!isEqual(myStack.pop(), stack.pop())) {
System.out.println("oops!");
}
}
}
int numq = (int) (Math.random() * value);
if (stack.isEmpty()) {
myQueue.push(numq);
queue.offer(numq);
} else {
if (Math.random() < 0.5) {
myQueue.push(numq);
queue.offer(numq);
} else {
if (!isEqual(myQueue.poll(), queue.poll())) {
System.out.println("oops!");
}
}
}
}
}
System.out.println("finish!");
}
}
c.用数组实现队列(常考题)(循环数组,用一个size巧妙解决问题)
package class2;
public class RingArray {
public static class MyQueue{
private int[] arr;
private int pushi;
private int polli;
private int size;
private final int limit;
public MyQueue(int limit) {
arr=new int[limit];
pushi=0;
polli=0;
size=0;
this.limit=limit;
}
public void push(int value) {
if(size==limit) {
throw new RuntimeException("队列满了,不能再加了");
}
size++;
arr[pushi]=value;
pushi=nextIndex(pushi);
}
public int pop() {
if(size==0) {
throw new RuntimeException("队列空了,不能再加了");
}
size--;
int ans=arr[polli];
polli=nextIndex(polli);
return ans;
}
public boolean isEmpty() {
return size==0;
}
private int nextIndex(int i) {
return i<limit-1?i+1:0;
}
}
}
d.队列实现栈
package class2;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class TwoQueueImplementStack {
public static class TwoQueueStack<T>{
public Queue<T> queue;
public Queue<T> help;
public TwoQueueStack() {
queue = new LinkedList<>();
help = new LinkedList<>();
}
public void push(T value) {
queue.offer(value);
}
public T poll() {
while(queue.size()>1) {
help.offer(queue.poll());
}
T ans=queue.poll();
Queue<T> tmp=queue;
queue=help;
help=tmp;
return ans;
}
public T peek() {
while(queue.size()>1) {
help.offer(queue.poll());
}
T ans=queue.poll();
help.offer(ans);
Queue<T> tmp=queue;
queue=help;
help=tmp;
return ans;
}
public boolean isEmpty() {
return queue.isEmpty();
}
}
public static void main(String[] args) {
System.out.println("test begin!");
TwoQueueStack<Integer> myStack=new TwoQueueStack<>();
Stack<Integer> test=new Stack<>();
int testTime=100000;
int max=100000;
for(int i=0;i<testTime;i++) {
if(myStack.isEmpty()) {
if(!test.isEmpty()) {
System.out.println("Oops");
}
int num=(int)(Math.random()*max);
myStack.push(num);
test.push(num);
}else {
if(Math.random()<0.25) {
int num=(int)(Math.random()*max);
myStack.push(num);
test.push(num);
}else if(Math.random()<0.5) {
if(!myStack.peek().equals(test.peek())) {
System.out.println("Oops");
}
}else if(Math.random()<0.75) {
if(!myStack.poll().equals(test.pop())) {
System.out.println("Oops");
}
}else {
if(myStack.isEmpty()!=test.isEmpty()) {
System.out.println("Oops");
}
}
}
}
System.out.println("test end!");
}
}
e.栈实现队列
package class2;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class TQS {
public static class TwoQueueStack<T> {
public Queue<T> queue;
public Queue<T> help;
public TwoQueueStack() {
queue = new LinkedList<>();
help = new LinkedList<>();
}
public void push(T value) {
queue.offer(value);
}
public T poll() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
T ans = queue.poll();
Queue<T> tmp = queue;
queue = help;
help = tmp;
return ans;
}
public T peek() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
T ans = queue.poll();
help.offer(ans);
Queue<T> tmp = queue;
queue = help;
help = tmp;
return ans;
}
public boolean isEmpty() {
return queue.isEmpty();
}
}
public static void main(String[] args) {
System.out.println("test begin");
TwoQueueStack<Integer> myStack = new TwoQueueStack<>();
Stack<Integer> test = new Stack<>();
int testTime = 1000000;
int max = 1000000;
for (int i = 0; i < testTime; i++) {
if (myStack.isEmpty()) {
if (!test.isEmpty()) {
System.out.println("Oops");
}
int num = (int) (Math.random() * max);
myStack.push(num);
test.push(num);
} else {
if (Math.random() < 0.25) {
int num = (int) (Math.random() * max);
myStack.push(num);
test.push(num);
} else if (Math.random() < 0.5) {
if (!myStack.peek().equals(test.peek())) {
System.out.println("Oops");
}
} else if (Math.random() < 0.75) {
if (!myStack.poll().equals(test.pop())) {
System.out.println("Oops");
}
} else {
if (myStack.isEmpty() != test.isEmpty()) {
System.out.println("Oops");
}
}
}
}
System.out.println("test finish!");
}
}
f.得到栈中最小值
package class2;
import java.util.Stack;
public class GetMinStack {
public static class Mystack1{
public Stack<Integer> stackData;
public Stack<Integer> stackMin;
public Mystack1() {
stackData=new Stack<>();
stackMin=new Stack<>();
}
public void push(int newNum) {
if(this.stackMin.isEmpty()) {
stackMin.push(newNum);
}else if(newNum<this.getmin()){
stackMin.push(newNum);
}
stackData.push(newNum);
}
public int pop() {
if(this.stackData.isEmpty()) {
throw new RuntimeException("Your stack is empty");
}
int value=this.stackData.pop();
if(value==this.getmin()) {
this.stackMin.pop();
}
return value;
}
public int getmin() {
if(this.stackMin.isEmpty()) {
throw new RuntimeException("Your stack is empty");
}
return this.stackMin.peek();
}
}
public static void main(String[] args) {
Mystack1 stack1=new Mystack1();
stack1.push(2);
stack1.push(1);
stack1.push(5);
stack1.push(4);
System.out.println(stack1.getmin());
System.out.println(stack1.pop());
System.out.println(stack1.pop());
System.out.println(stack1.pop());
System.out.println(stack1.getmin());
}
}
五.哈希表的用法
package class2;
import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeMap;
public class HM {
public static class Node {
public int value;
public Node(int v) {
value = v;
}
}
public static class Zuo {
public int value;
public Zuo(int v) {
value = v;
}
}
public static void main(String[] args) {
HashMap<Integer, String> test = new HashMap<>();
Integer a = 19000000;
Integer b = 19000000;
System.out.println(a == b);
test.put(a, "我是3");
System.out.println(test.containsKey(b));
Zuo z1 = new Zuo(1);
Zuo z2 = new Zuo(1);
HashMap<Zuo, String> test2 = new HashMap<>();
test2.put(z1, "我是z1");
System.out.println(test2.containsKey(z2));
// UnSortedMap
HashMap<Integer, String> map = new HashMap<>();
map.put(1000000, "我是1000000");
map.put(2, "我是2");
map.put(3, "我是3");
map.put(4, "我是4");
map.put(5, "我是5");
map.put(6, "我是6");
map.put(1000000, "我是1000001");
System.out.println(map.containsKey(1));
System.out.println(map.containsKey(10));
System.out.println(map.get(4));
System.out.println(map.get(10));
map.put(4, "他是4");
System.out.println(map.get(4));
map.remove(4);
System.out.println(map.get(4));
// key
HashSet<String> set = new HashSet<>();
set.add("abc");
set.contains("abc");
set.remove("abc");
// 哈希表,增、删、改、查,在使用时,O(1)
System.out.println("=====================");
Integer c = 100000;
Integer d = 100000;
System.out.println(c.equals(d));
Integer e = 127; // - 128 ~ 127
Integer f = 127;
System.out.println(e == f);
HashMap<Node, String> map2 = new HashMap<>();
Node node1 = new Node(1);
Node node2 = node1;
map2.put(node1, "我是node1");
map2.put(node2, "我是node1");
System.out.println(map2.size());
System.out.println("======================");
// TreeMap 有序表:接口名
// 红黑树、avl、sb树、跳表
// O(logN)
System.out.println("有序表测试开始");
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(3, "我是3");
treeMap.put(4, "我是4");
treeMap.put(8, "我是8");
treeMap.put(5, "我是5");
treeMap.put(7, "我是7");
treeMap.put(1, "我是1");
treeMap.put(2, "我是2");
System.out.println(treeMap.containsKey(1));
System.out.println(treeMap.containsKey(10));
System.out.println(treeMap.get(4));
System.out.println(treeMap.get(10));
treeMap.put(4, "他是4");
System.out.println(treeMap.get(4));
// treeMap.remove(4);
System.out.println(treeMap.get(4));
System.out.println("新鲜:");
System.out.println(treeMap.firstKey());
System.out.println(treeMap.lastKey());
// <= 4
System.out.println(treeMap.floorKey(4));
// >= 4
System.out.println(treeMap.ceilingKey(4));
// O(logN)
}
}
六.归并排序实现和应用
1.递归和迭代实现归并排序
package mergeSort;
public class MS {
public static void mergeSort1(int[] arr) {
if(arr==null || arr.length<2) {
return;
}
process(arr,0,arr.length-1);
}
public static void process(int[] arr,int L,int R) {
if(L==R) {
return;
}
int M=L+((R-L)>>1);
process(arr,L,M);
process(arr,M+1,R);
merge(arr,L,M,R);
}
public static void merge(int[] arr,int L,int M,int R) {
int[] help=new int[R-L+1];
int p1=L;
int p2=M+1;
int i=0;
while(p1<=M && p2<=R) {
help[i++]=arr[p1]<=arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=M) {
help[i++]=arr[p1++];
}
while(p2<=R) {
help[i++]=arr[p2++];
}
for(i=0;i<help.length;i++) {
arr[i+L]=help[i];
}
}
public static void mergeSort2(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
int N = arr.length;
// 步长
int mergeSize = 1;
while (mergeSize < N) { // log N
// 当前左组的,第一个位置
int L = 0;
while (L < N) {
if (mergeSize >= N - L) {
break;
}
int M = L + mergeSize - 1;
int R = M + Math.min(mergeSize, N - M - 1);
merge(arr, L, M, R);
L = R + 1;
}
// 防止溢出
if (mergeSize > N / 2) {
break;
}
mergeSize <<= 1;
}
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
mergeSort1(arr1);
mergeSort2(arr2);
if (!isEqual(arr1, arr2)) {
System.out.println("出错了!");
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println("测试结束");
}
}
2.应用
a)小和问题(左边的数比右边小的数的和)
package mergeSort;
public class SmallSum {
public static int smallSum(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
return process(arr, 0, arr.length - 1);
}
public static int process(int[] arr,int l,int r) {
if(l==r) {
return 0;
}
int m=l+((r-l)>>1);
return process(arr,l,m)+process(arr,m+1,r)+merge(arr,l,m,r);
}
public static int merge(int[] arr,int l,int m,int r) {
int[] help=new int[r-l+1];
int i=0;
int p1=l;
int p2=m+1;
int res=0;
while(p1<=m && p2<=r) {
res+=arr[p1]<arr[p2]?(r-p2+1)*arr[p1]:0;
help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];
}
while(p1<=m) {
help[i++]=arr[p1++];
}
while(p2<=r) {
help[i++]=arr[p2++];
}
for(int j=0;j<help.length;j++) {
arr[j+l]=help[j];
}
return res;
}
// arr[L..R]既要排好序,也要求小和返回
// 所有merge时,产生的小和,累加
// 左 排序 merge
// 右 排序 merge
// merge
// public static int process(int[] arr, int l, int r) {
// if (l == r) {
// return 0;
// }
// // l < r
// int mid = l + ((r - l) >> 1);
// return
// process(arr, l, mid)
// +
// process(arr, mid + 1, r)
// +
// merge(arr, l, mid, r);
// }
//
// public static int merge(int[] arr, int L, int m, int r) {
// int[] help = new int[r - L + 1];
// int i = 0;
// int p1 = L;
// int p2 = m + 1;
// int res = 0;
// while (p1 <= m && p2 <= r) {
// res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
// help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
// }
// while (p1 <= m) {
// help[i++] = arr[p1++];
// }
// while (p2 <= r) {
// help[i++] = arr[p2++];
// }
// for (i = 0; i < help.length; i++) {
// arr[L + i] = help[i];
// }
// return res;
// }
// for test
// public static int comparator(int[] arr) {
// if (arr == null || arr.length < 2) {
// return 0;
// }
// int res = 0;
// for (int i = 1; i < arr.length; i++) {
// for (int j = 0; j < i; j++) {
// res += arr[j] < arr[i] ? arr[j] : 0;
// }
// }
// return res;
// }
public static int comparator(int[] arr) {
if(arr==null || arr.length<2) {
return 0;
}
int sum=0;
for(int i=1;i<arr.length;i++) {
for(int j=0;j<i;j++) {
sum+=arr[j]<arr[i]?arr[j]:0;
}
}
return sum;
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 100;
int maxValue = 100;
boolean succeed = true;
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
if (smallSum(arr1) != comparator(arr2)) {
succeed = false;
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
}
b)逆序对问题(求右比左小的个数)
package mergeSort;
public class reverseCouple {
public static int smallSum(int[] arr) {
if (arr == null || arr.length < 2) {
return 0;
}
return process(arr, 0, arr.length - 1);
}
public static int process(int[] arr,int l,int r) {
if(l==r) {
return 0;
}
int m=l+((r-l)>>1);
return process(arr,l,m)+process(arr,m+1,r)+merge(arr,l,m,r);
}
public static int merge(int[] arr,int l,int m,int r) {
int[] help=new int[r-l+1];
int i=help.length-1;
int p1=m;
int p2=r;
int res=0;
while(p1>=l && p2>m) {
res+=arr[p1]>arr[p2]?(p2-m):0;
help[i--]=arr[p1]>arr[p2]?arr[p1--]:arr[p2--];
}
while(p1>=l) {
help[i--]=arr[p1--];
}
while(p2>m) {
help[i--]=arr[p2--];
}
for(int j=0;j<help.length;j++) {
arr[j+l]=help[j];
}
return res;
}
public static int comparator(int[] arr) {
if(arr==null || arr.length<2) {
return 0;
}
int sum=0;
for(int i=0;i<arr.length;i++) {
for(int j=i+1;j<arr.length;j++) {
if(arr[i]>arr[j]) {
sum++;
}
}
}
return sum;
}
// for test
public static int[] generateRandomArray(int maxSize, int maxValue) {
int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
}
return arr;
}
// for test
public static int[] copyArray(int[] arr) {
if (arr == null) {
return null;
}
int[] res = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
res[i] = arr[i];
}
return res;
}
// for test
public static boolean isEqual(int[] arr1, int[] arr2) {
if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {
return false;
}
if (arr1 == null && arr2 == null) {
return true;
}
if (arr1.length != arr2.length) {
return false;
}
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i]) {
return false;
}
}
return true;
}
// for test
public static void printArray(int[] arr) {
if (arr == null) {
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// for test
public static void main(String[] args) {
int testTime = 500000;
int maxSize = 10;
int maxValue = 100;
boolean succeed = true;
// int[] arr1 = generateRandomArray(maxSize, maxValue);
// printArray(arr1);
// int[] arr2 = copyArray(arr1);
// printArray(arr2);
for (int i = 0; i < testTime; i++) {
int[] arr1 = generateRandomArray(maxSize, maxValue);
int[] arr2 = copyArray(arr1);
int a=smallSum(arr1);
int b=comparator(arr2);
if ( a!=b ) {
printArray(arr1);
printArray(arr2);
succeed = false;
System.out.println("a:"+a);
System.out.println("b:"+b);
break;
}
}
System.out.println(succeed ? "Nice!" : "Fucking fucked!");
}
}