1、
描述
给定一个正整数数组,请求出自第一个元素开始到每个元素为终点的中位数。
输入
第一行:N(1<N<=1000),代表数组的长度
第二行:N个整数,作为数组的元素,空格分开
输出
N个整数,空格隔开;第一位是数组第一个元素,第二位是前两个元素的上中位数……
样例输入
5
4 6 9 4 5
样例输出
4 4 6 4 5
import java.util.Arrays;
import java.util.Scanner;
class Main{
public static void main(String[] args) {
int x;
int mid = 0;
Scanner sc = new Scanner(System.in);
x = sc.nextInt();
int arr[] = new int[x];
for(int i=0;i<x;i++){
arr[i] = sc.nextInt();
}
for(int i=0;i<x;i++){
int [] copy = Arrays.copyOfRange(arr,0,i+1);
Arrays.sort(copy);
mid = copy[i/2];
System.out.print(mid+" ");
}
}
}
2、
描述
数组小和的定义如下:
例如:数组s = [1, 3, 5, 2, 4, 6],在s[1]的左边小于或等于s[1]的数的和为1,在s[2]的左边小于或等于s[2]的数有1和3,求和为4,……,将所有位置的左边比它小或者等于的数的和相加起来就是真个数组的小和。
给定一个数组,输出数组的小和。
输入
第一行:N(1<N<=100000),代表数组的长度
第二行:N个整数(<=100),作为数组的元素,空格分开
输出
数组的小和
样例输入
5
58 74 14 39 15
样例输出
86
思路:
不要爆破 我们要转变思想把当前数前面比她小的和转变为当前数要被加几次(就是跟后面数做比较,后面数比当前数大,就要加一次),这个正符合归并排序,每次比较,我们需要改进的是在比较是若后面数比当前数大,sum就加当前数,只需加一句:smallSum += s[i] * (right - j+ 1);
public class test3 {
public static void merSort(int[] arr,int left,int right){
if(left<right){
int mid = (left+right)/2;
merSort(arr,left,mid);//左边归并排序,使得左子序列有序
merSort(arr,mid+1,right);//右边归并排序,使得右子序列有序
merge(arr,left,mid,right);//合并两个子序列
}
}
static int smallsum =0;
private static void merge(int[] arr, int left, int mid, int right) {
int[] temp = new int[right - left + 1];//ps:也可以从开始就申请一个与原数组大小相同的数组,因为重复new数组会频繁申请内存
int i = left;
int j = mid+1;
int k = 0;
while(i<=mid&&j<=right){
if (arr[i] < arr[j]) {
smallsum+= arr[i]*(right-j+1);
} else {
temp[k++] = arr[j++];
}
}
while(i<=mid){//将左边剩余元素填充进temp中
temp[k++] = arr[i++];
}
while(j<=right){//将右序列剩余元素填充进temp中
temp[k++] = arr[j++];
}
//将temp中的元素全部拷贝到原数组中
for (int k2 = 0; k2 < temp.length; k2++) {
arr[k2 + left] = temp[k2];
}
}
public static void main(String args[]){
int[] test = {9,2,6,3,5,7,10,11,12};
merSort(test,0,test.length-1);
for(int i=0; i<test.length;i++){
System.out.print(test[i] + " ");
}
System.out.println(smallsum);
}
}
这个是我的代码,,但是有问题,,输出不出来??
copy了别人的一份正确代码
public class test{
public static int getSmallSum(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
return func(arr, 0, arr.length - 1);
}
public static int func(int[] s, int l, int r) {
if (l == r) {
return 0;
}
int mid = (l + r) / 2;
return func(s, l, mid) + func(s, mid + 1, r) + merge(s, l, mid, r);
}
public static int merge(int[] s, int left, int mid, int right) {
int[] h = new int[right - left + 1];
int hi = 0;
int i = left;
int j = mid + 1;
int smallSum = 0;
while (i <= mid && j <= right) {
if (s[i] <= s[j]) {
smallSum += s[i] * (right - j + 1);
h[hi++] = s[i++];
} else {
h[hi++] = s[j++];
}
}
for (; (j < right + 1) || (i < mid + 1); j++, i++) {
h[hi++] = i > mid ? s[j] : s[i];
}
for (int k = 0; k != h.length; k++) {
s[left++] = h[k];
}
return smallSum;
}
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
public static void main(String[] args) {
int[] arr = { 58, 74, 14, 39, 15 };
System.out.println(getSmallSum(arr));
}
}
3、
描述
给定一个数组,求最小的K个数。由于数组规模很大,请精心设计算法。
输入
第一行:N(1<N<=100000),代表数组的长度
第二行:K(<=1000,<N),代表求从小到大的K个数
第三行:N个整数,作为数组的元素,空格分开
输出
从小到大输出K个数组中最小的数,空格隔开
思路:利用堆排序,特别适用于海量数据中寻找最大或者最小的k个数字。即构建一个大堆容器,初始化大小为k,变量初始数,如初始数组大小小于等于k直接返回,如果大于k,则选择数组的前k个元素,填充堆,然后调整为最大堆。调整完之后,继续从初始数组中拿出一个元素,如果该元素比大堆的堆顶小,则替换堆顶,继续调整为最大堆,如果大于等于堆顶则直接丢弃,不作调整。
PS:大堆还是小堆的选择很重要,不是寻找最小的k个元素就要选择小堆,而且恰恰相反。寻找最小的k个数,其实就是寻找第k个大的元素,即寻找k个数中最大的,不断调整堆,堆得元素个数是k,堆顶是最大值,遍历完初始数组后,堆中存在的元素即使我们所要寻找的k个最小元素。
import java.util.Scanner;
class Main{
static int[] heap;
static int index = 0;
static int k;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int count = sc.nextInt();
k = sc.nextInt();
heap = new int[k];
int x=0;
for(int i=0;i<count;i++){
x = sc.nextInt();
deal(x);
}
for(int i=k-1;i>=0;i--){
System.out.print(heap[i]+" ");
}
}
static void deal(int x){
if(index<k){
heap[index++] = x;
if(index == k){
makeMinHeap(heap); //堆化
}
}else {
if(heap[0]>x){ //如果找最小的数,就选大顶堆,,如果x>heap[0],x就把他挤掉并向下调整
heap[0] =x;
MinHeapFixDown(heap,0,k);
}
}
}
static void makeMinHeap(int [] heap){
int n = heap.length;
for(int i=n/2-1;i>=0;i--){
MinHeapFixDown(heap,i,n);
}
}
static void MinHeapFixDown(int[] heap,int i,int n){
int left = 2*i+1;
int right = 2*i+2;
if( left>=n){
return;
}
int max = left;
if(right>=n){
max = left;
}else{
if(heap[right]>heap[left]){
max = right;
}
}
if(heap[i]>heap[max]){
return;
}
int temp = heap[i];
heap[i] = heap[max];
heap[max] = temp;
MinHeapFixDown(heap,max,n);
}
}
4、
给定一个字符串类型的数组strs,请找到一种拼接顺序,使得将所有的字符串拼接起来组成的大字符串是所有可能性中字典顺序最大的,并输出这个大字符串。
输入
第一行:N(1<N<=100),代表数组的长度
第二行:N个字符串,作为数组的元素,空格分开,字符串长度<=10
输出
字典序最大的大字符串
样例输入
5 a ac ab def d
样例输出
defdacaba
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x= sc.nextInt();
String a[] = new String[x];
for (int i=0;i<x;i++){
String st1 = sc.next();
a[i] = st1;
}
lowstring(a);
System.out.println(res);
}
static String res = "";
static String lowstring (String[] a){
if(a==null || a.length==0) {
return "";
}
Arrays.sort(a,new Mycomparator());
for(int i=0;i<a.length;i++){
res+= a[i];
}
return res;
}
static class Mycomparator implements Comparator<String>{
@Override
public int compare(String s, String t1) {
return(t1+s).compareTo(s+t1);
}
}
}
5、
一般我们在对字符串排序时,都会按照字典序排序。当字符串只包含小写字母时,相当于按字母表"abcdefghijklmnopqrstuvwxyz"的顺序排序。
现在我们打乱字母表的顺序,得到一个26个字母的新顺序:bdceafghijklmnopqrstuvwxyz,代表'b'排在'd'前,'d'在'c'前,'c'在'e'前……
给定N个字符串,请你按照新的字母顺序对它们排序。
输入
第一行包含一个整数N。(1 <= N <= 1000)
第二行包含26个字母,代表新的顺序。
以下N行每行一个字符串S。 (|S| <= 100)
输出
按新的顺序输出N个字符串,每个字符串一行。
样例输入
5 bdceafghijklmnopqrstuvwxyz abcde adc cda cad ddc
样例输出
ddc cda cad abcde adc
额。。。。。这道题好想吐槽,java字符串修改要用char,字符串排序要用string,换来换去好麻烦
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int n;
static int[] ma=new int[26];
static int[] jie=new int[26];
static String a=new String();
static char[][] b=new char[1005][105];
static String[] ans=new String[1005];
public static void main(String args[]) {
Scanner in=new Scanner(System.in);
n=in.nextInt();
a=in.next();
for(int i=0;i<a.length();i++) {
ma[i]=a.charAt(i)-'a';
jie[a.charAt(i)-'a']=i;
}
for(int i=0;i<n;i++) {
a=in.next();
b[i]=a.toCharArray();
for(int j=0;j<b[i].length;j++) {
b[i][j]=(char)(jie[b[i][j]-'a']+'a');
}
ans[i]=String.valueOf(b[i]);
}
Arrays.sort(ans,0,n);
for(int i=0;i<n;i++) {
b[i]=ans[i].toCharArray();
for(int j=0;j<b[i].length;j++) {
b[i][j]=(char)(ma[b[i][j]-'a']+'a');
}
System.out.println(b[i]);
}
}
}