1、寻找第K大
链接:
https://www.nowcoder.com/questionTerminal/e016ad9b7f0b45048c58a9f27ba618bf
//1.快排
public class Main {
public static int findKth(int[] array, int n, int K) {
return quick(array,0,n-1,K);
}
public static int quick(int[] array, int low, int high,int K) {
int par = partion(array, low, high);
if(K == par - low + 1) {
return array[par];
}else if(K > par - low + 1) {
return quick(array, par + 1, high, K - par + low -1);
}else {
return quick(array, low, par -1, K);
}
}
//找基准
public static int partion(int[] array,int start,int end) {
int tmp = array[start];
while(start < end) {
while(start < end && array[end] <= tmp) {
end--;
}
if(start >= end) {
array[start] = tmp;
break;
}else {
array[start] = array[end];
}
while(start < end && array[start] >= tmp) {
start++;
}
if(start >= end) {
array[start] = tmp;
break;
}else {
array[end] = array[start];
}
}
return start;
}
}
//2.优先级队列
public static int findKth1(int[] array, int n, int K) {
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
for(int m : array){
//堆中元素不够K个或者将要放的元素比堆顶元素大,就往堆中放元素
if(priorityQueue.size() < K || priorityQueue.peek() <= m){
priorityQueue.offer(m);
}
// 保持堆大小为K
if(priorityQueue.size() > K){
priorityQueue.poll();
}
}
return priorityQueue.peek();
}
2、数组中的逆序对
链接:
https://www.nowcoder.com/questionTerminal/bb06495cc0154e90bbb18911fd581df6
思路:分治思想,采用归并排序的思路来处理。先分后治:先把数组分隔成子数组,先统计出子数组内部的逆序对的数目,然后再统计出两个相邻子数组之间的逆序对的数目。在统计逆序对的过程中,还需要对数组进行排序,其实这个排序过程就是归并排序的思路。
逆序对的总数=左边数组中的逆序对的数量+右边数组中逆序对的数量+左右结合成新的顺序数组时中出现的逆序对的数量。
public class Main {
public static int count(int[] A, int n) {
if(A == null || n == 0) {
return 0;
}
return mergeSortRecursion(A,0,n-1);
}
public static int mergeSortRecursion(int[] array,int left,int right) {
if(left == right) {
return 0;
}
int mid = (right + left)/2;
return mergeSortRecursion(array,left,mid)+mergeSortRecursion(array,mid+1,right)
+merge(array,left,mid,right);
}
public static int merge(int[] array,int left,int mid,int right) {
int s1 = left;
int s2 = mid+1;
int n = 0;
int[] tmpArr = new int[right-left+1];
int k = 0;//数组tmp的下标
//代表两个段都有数据
while(s1 <= mid && s2 <= right) {
if(array[s1] <= array[s2]) {
tmpArr[k++] = array[s1++];
}else {
n += (mid - s1 + 1);//累加逆序对
tmpArr[k++] = array[s2++];
}
}
//第一个归并段还有若干个数据
while(s1 <= mid) {
tmpArr[k++] = array[s1++];
}
while(s2 <= right) {
tmpArr[k++] = array[s2++];
}
//tmpArr中存放的就是这次归并的有序之后的结果
for (int i = 0; i < tmpArr.length ; i++) {
array[left++] = tmpArr[i];
}
return n;
}
}
3、删除公共字符
链接:
https://www.nowcoder.com/questionTerminal/f0db4c36573d459cae44ac90b90c6212
思路:最简单的思路就是两层循环遍历,下面将“They are students.”称为字符串1,将“aeiou”称为字符串2。每遍历到字符串2中的一个字符,就在字符串1中找到相同的字符,找到之后删除它,并将字符串1后面的字符整体向前移动位。
import java.util.*;
public class Main{
public static void main(String args[]) {
Scanner sca = new Scanner(System.in);
while(sca.hasNext()) {
String s1 = sca.nextLine();
char[] ch = s1.toCharArray();
String s2 = sca.nextLine();
for(int i=0;i<ch.length;i++) {
if(!s2.contains(String.valueOf(ch[i]))) {
System.out.print(ch[i]);
}
}
}
}
}