数组问题

通过相邻交换,让相同的数相邻

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] array = new int[2*n];
        for (int i = 0; i < array.length; i++) {
            array[i]=sc.nextInt();
        }
        int count=0;
        for (int i = 0; i < array.length; i++) {
            int t=array[i];
            if (t==0){
                continue;
            }
            int dis=0;
            for (int j = i+1; j < array.length; j++) {
                 if (t==array[j]){
                     array[j]=0;
                     break;
                 }else if (array[j]!=0){
                    dis++;
                 }
            }
            count+=dis;
        }
        System.out.println(count);
    }
}




两两配对差值最小

给定一个长度为偶数的数组arr,将该数组中的数字两两配对并求和,在这些和中选出最大和最小值,请问该如何两两配对,才能让最大值和最小值的差值最小?

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] array = new int[n];
        for (int i = 0; i < n; i++) {
            array[i]=sc.nextInt();
        }
        Arrays.sort(array);
        int b=0;
        int e=array.length-1;
        int max=Integer.MIN_VALUE;
        int min=Integer.MAX_VALUE;
        while (b<e){
            int tmp=array[b++]+array[e--];
            if (tmp>max) max=tmp;
            if (tmp<min) min=tmp;
        }
        System.out.println(max-min);
    }
}

数组中三个数的乘积最大

package lockDemo;

import org.omg.PortableInterceptor.LOCATION_FORWARD;

import java.util.Scanner;

public class Main {

    public static Long findMax(Long[] array,int begin, int end){
        Long tmp;
        for (int i = begin; i < end-1; i++) {
            if(array[i]>array[i+1]){
                tmp=array[i];
                array[i]=array[i+1];
                array[i+1]=tmp;
            }
        }
        return array[end-1];
    }
    public static Long findMin(Long[] array,int begin,int end){
        Long tmp;
        for (int i = end-1; i >0; i--) {
            if(array[i]<array[i-1]){
                tmp=array[i];
                array[i]=array[i-1];
                array[i-1]=tmp;
            }
        }
        return array[begin];
    }

    public static void main(String[] args) {
        Scanner sc1 = new Scanner(System.in);

        while (sc1.hasNextLine()){
            String s = sc1.nextLine();
            if(s!=null){
                String[] split = s.split(" ");
                if(split.length>=3){
                    Long[] a=new Long[split.length];
                    for (int i = 0; i < split.length; i++) {
                        a[i]=Long.parseLong(split[i]);
                    }
                    if(split.length==3){
                        System.out.println(a[0]*a[1]*a[2]);
                        return;
                    }
                    Long firstMax=findMax(a,0,a.length);
                    Long secondMax=findMax(a,0,a.length-1);
                    Long thirdMax=findMax(a,0,a.length-2);
                    Long firstMin=findMin(a,0,a.length-3);
                    Long secondMin=findMin(a,1,a.length-3);
                    if(firstMax<0||firstMin>0){
                        System.out.println(firstMax*secondMax*thirdMax);
                    } else if(firstMin<0&&secondMin<0&&firstMax>0&&(firstMin*secondMin*firstMax)>(firstMax*secondMax*thirdMax)){
                        System.out.println(firstMin*secondMin*firstMax);
                    }else {
                        System.out.println(firstMax*secondMax*thirdMax);
                    }
                }
            }
        }
        }
}

如何寻找数组中的最小值和最大值

取双元素法:

int[] array = {2, 3, 1, 4, 6, 4, 8, 10};
        int min=Integer.MAX_VALUE;
        int max=Integer.MIN_VALUE;
        int i=0;
        while (i+1<array.length){
            int e1 = array[i];
            int e2 = array[++i];
            if (e1>e2){
                max=max<e1?e1:max;
                min=min>e2?e2:min;
            }else {
                max=max<e2?e2:max;
                min=min>e1?e1:min;
            }
        }
        System.out.println(max+" "+min);
    }

取数组中的第二大元素

定义一个最大元素max,第二大元素sec_max

int max=array[0];
        int sec_max=Integer.MIN_VALUE;
        for (int i = 1; i < array.length; i++) {
            if (max<array[i]){
                sec_max=max;
                max=array[i];
            }
        }
        System.out.println(sec_max);

数组中两两相加之和等于20的对数

public static void main(String[] args) {
        int[] array = {1, 7, 17, 2, 6, 3, 14};
        Arrays.sort(array);
        int num=20;
        int begin=0;
        int end=array.length-1;
        while (begin<end){
            if (array[begin]+array[end]<num){
                begin++;
            }else if (array[begin]+array[end]>num){
                end--;
            }else {
                System.out.println(array[begin]+" "+array[end]);
                begin++;
                end--;
            }
        }
    }

把一个数组循环右移K位

12345678,右移2位为78123456

654321 87取逆序为78123456

public class C6 {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 4, 5, 6, 7, 8};
        int k=2;
        shift_k(array,k);
        System.out.println(Arrays.toString(array));

    }

    private static void shift_k(int[] array, int k) {
        int n = array.length;
        k=k%n;
        reverse(array,n-k,n-1);
        reverse(array,0,n-k-1);
        reverse(array,0,n-1);
    }

    private static void reverse(int[] array, int b, int e) {
        while (b<e){
            int tmp=array[b];
            array[b]=array[e];
            array[e]=tmp;
            b++;
            e--;
        }
    }
}

排序查找数组中第k小的数

方法一:从小到大排序,找出第k-1位置的树;
方法二:按照快排的思想,选一个数tmp=a[n-1],比他小的数都放在左边,比它大的数都放在右边,然后判断tmp所在位置是否为k-1;如果不是则判断它的位置小于k-1还是于k-1然后在递归在左右两边查找。

public class QueckSort {
    public static void main(String[] args) {
        int[] array = {1, 5, 2, 6, 8, 0, 6};
        int k=4;
        System.out.println(queckSelect(array,k));

    }

    private static int queckSelect(int[] array,int k) {
        if (array==null){
            return 0;
        }
        return sort(array,0,array.length-1,k);
    }

    private static int sort(int[] array, int begin, int end,int k) {
        if (begin>end){
            return 0;
        }
        int i=begin+1;
        int j=end;
        int mid=array[i];
        while (i<j){
            while (i<j&&array[j]>=mid){
                j--;
            }
            if (i<j){
                array[i++]=array[j];
            }

            while (i<j&&array[i]<mid){
                i++;
            }
            if (i<j){
                array[j--]=array[i];
            }

        }
        array[i]=mid;
        if (i<k-1){
            return sort(array,i+1,end,k);
        }else if (i>k-1){
            return sort(array,begin,i-1,k);
        }else {
            return array[i];
        }


    }
}

如何找出数组中只出现一次的数字

如果只有一个数字出现一次,其他数字出现偶数次

使用异或;

int[] array = {1, 2, 3, 2, 4, 3, 5, 4, 1};
        int result=array[0];
        for (int i = 1; i < array.length; i++) {
            result^=array[i];
        }
        System.out.println(result);

如果只有一个数字出现一次,其他数字出现奇数n次

数组[1,1,1,2,2,2,3];

01,01,01,10,10,10,11
出现一次的数字二进制对应位上1的个数不能被n整除,找到这些位,就是这个数字的二进制形式;

public class C10 {
    public static void main(String[] args) {
        int[] array = {1, 1,1,2,2,2,3};
        int n=3;
        int[] dp = new int[32];
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < 32; j++) {
                if ((array[i]>>j&1)==1){
                    dp[j]++;
                }
            }
        }
        int num=0;
        for (int i = 0; i < dp.length; i++) {
            if (dp[i]%n!=0){
                num+=Math.pow(2,i);
            }
        }
        System.out.println(num);
    }
}

给定一个闭区间[a,b],求出这个区间中能整除给定数c的个数

方法一:循环遍历记录个数;
方法二:使用除法,区间两端点除以k的商,两个商之间的整数个数;

private static int m1(int a, int b, int c) {

        if (a==b){
            if (a%c==0){
                return 1;
            }else {
                return 0;
            }
        }
        return a/c+b/c+1;
    }

用递归的方式求一个数组中的最大元素

public static void main(String[] args) {
        int[] array = {0, 16, 2, 3, 4, 5, 10, 7, 8, 9};
        System.out.println(maxNum(array,0));

    }

    private static int maxNum(int[] array, int begin) {
        int length=array.length-begin;
        if (length==1){
            return array[begin];
        }
        return Math.max(array[begin],maxNum(array,begin+1));
    }

如何求出数对之差的最大值

public static void main(String[] args) {
        int[] array = {1, 4, 17, 3, 2, 9};
        int diff=0;
        int max=array[0];
        for (int i = 1; i < array.length; i++) {
            diff=Math.max(diff,max-array[i]);
            max=Math.max(max,array[i]);
        }
        System.out.println(diff);
    }

如何求出升序数组中绝对值最小的数

public static void main(String[] args) {
        int[] array = {-10, -5, -2, 7, 15, 50};
        System.out.println(getMinAbsoluteValue(array));
    }

    private static int getMinAbsoluteValue(int[] array) {
        if (array[0]>=0){
            return array[0];
        }
        if (array[array.length-1]<=0){
            return array[array.length-1];
        }
        for (int i = 0; i < array.length-1; i++) {
            if (array[i]*array[i+1]<=0){
                if (array[i]*array[i+1]==0){
                    return 0;
                }else {
                    return 0-array[i]>array[i+1]?array[i+1]:array[i];
                }
            }
        }
        return 0;
    }

如何找出数组中唯一重复的元素

统计数组中出现频率前k的元素

public List<Integer> topKFrequent(int[] nums, int k) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            map.put(num,map.getOrDefault(num,0)+1);
        }
        PriorityQueue<Integer> heap = new PriorityQueue<>((n1,n2)->{
            return map.get(n1)-map.get(n2);
        });
        for (Integer n : map.keySet()) {
            heap.add(n);
            if (heap.size()>k){
                heap.poll();
            }
        }
        ArrayList<Integer> list=new ArrayList<>();
        while(!heap.isEmpty()){
            list.add(heap.poll());
        }
        Collections.reverse(list);
        return list;
    }

长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。

class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int i=0;
        int j=0;
        int sum=0;
        int result=Integer.MAX_VALUE;
        while(j<nums.length){
            if(sum+nums[j]>=s){
                result=Math.min(result,j-i+1);
                sum-=nums[i++];
            }else{ 
                sum+=nums[j++];
            }
        }
        return result==Integer.MAX_VALUE?0:result;
    }
}

杨辉三角

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> list=new ArrayList<>();
        for(int i=0;i<numRows;i++){
            List<Integer> childList=new ArrayList<>();
            if(i==0){
                childList.add(1);
                list.add(childList);
                continue;
            }
            for(int j=0;j<=i;j++){
                if(j==0){
                    childList.add(1);
                }else if(j==i){
                    childList.add(1);
                }else{
                    childList.add(list.get(i-1).get(j-1)+list.get(i-1).get(j));
                }
            }
            list.add(childList);
        }
        return list;
    }
}

三角形最小路径和

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

在这里插入图片描述

自底向上,空间复杂度O(n^2)

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int len=triangle.size();
        int[][] dp=new int[len][len];
        for(int k=0;k<=len-1;k++){
            dp[len-1][k]=triangle.get(len-1).get(k);
        }
        for(int i=len-2;i>=0;i--){
            List<Integer> list=triangle.get(i);
            int size=list.size();
            for(int j=0;j<size;j++){
                dp[i][j]=Math.min(dp[i+1][j],dp[i+1][j+1])+triangle.get(i).get(j);
            }
        }
        return dp[0][0];
    }
}

空间复杂度O(n)

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int len=triangle.size();
        int[] dp=new int[len];
        for(int k=0;k<=len-1;k++){
            dp[k]=triangle.get(len-1).get(k);
        }
        for(int i=len-2;i>=0;i--){
            List<Integer> list=triangle.get(i);
            int size=list.size();
            for(int j=0;j<size;j++){
                dp[j]=Math.min(dp[j],dp[j+1])+triangle.get(i).get(j);
            }
        }
        return dp[0];
    }
}

买卖股票的最佳时机I

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length==0||prices==null){
            return 0;
        }
        int minElem=Integer.MAX_VALUE;
        int maxPrice=Integer.MIN_VALUE;
        for(int i=0;i<prices.length;i++){
            minElem=Math.min(prices[i],minElem);
            maxPrice=Math.max(maxPrice,prices[i]-minElem);
        }
        return maxPrice;
        
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值