通过相邻交换,让相同的数相邻
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;
}
}