【Java版】牛客编程题:寻找第K大、数组中的逆序对、删除公共字符串

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]);
                }
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值