数组
2021/4/2
1.LC寻找两个正序数组的中位数
给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
1.暴力破解法
思路:先将两数组合并,再排序,得到一个新的数组。然后分类讨论,如果为奇数数组,则‘/2’,得到中位数;如果为偶数数组,则‘/2’,得到一个数,然后序号加1,得到后一个数,两数相加再除2,得到中位数。
代码:
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int strLen1=nums1.length;//保存第一个数组长度
int strLen2=nums2.length;//保存第二个数组长度
nums1= Arrays.copyOf(nums1,strLen1+ strLen2);//扩容
System.arraycopy(nums2, 0, nums1, strLen1,strLen2 );//将第二个数组与第一个数组合并
Arrays.sort(nums1);
if (nums1.length%2 == 1){
double median = nums1[nums1.length/2];
// System.out.println(median);
return median;
}else{
double median = (double)(nums1[nums1.length/2]+nums1[nums1.length/2-1])/2;
// System.out.println(median);
return median;
}
}
}
难点:
- 数组合并,通过Arrays.copyof()和System.arraycopy()函数进行合并
- 如何保留小数不被整除?在前面加上(double)。
2.二分查找法(不会)
2021/4/5
专题:链表
2021/4/7
剑指offer
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1,2,8,9],
[2,4,9,12],
[4,7,10,13],
[6,8,11,15]
]
给定 target = 7,返回 true。
给定 target = 3,返回 false。
输入
7,[[1,2,8,9],[2,4,9,12],[4,7,10,13],[6,8,11,15]]
返回值
true
思路
- 暴力破解法。将二维数组循环遍历两边,然后通过if比对,输出结果
public class Solution {
public boolean Find(int target, int [][] array) {
for (int i = 0; i < array.length; i++){
for(int j = 0; j < array[i].length; j++){
if(target == array[i][j]){
return true;
}
}
}
return false;
}
}
-
二分查找。
二分查找的原理是:将1个排从小到大(从大到小)的数,分别在头和尾设置m,n,在中间设立mid=(m+n)/2,然后目标数为tar,如果mid>tar,则将mid变成尾,在m和mid之间寻找tar,再设置一个新的mid2=(m+mid)/2,以此类推,直到找到tar为止;如果mid<tar,则相反。
public class Solution {
public boolean Find(int target, int [][] array) {
// 判断数组是否为空
int m = array.length;
if (m == 0) return false;
int n = array[0].length;
if (n == 0) return false;
int r = 0, c = n-1; // 右上角元素
while (r<m && c>=0) {
if (target == array[r][c]) {
return true;
}
else if (target > array[r][c]) {
++r;
}
else {
--c;
}
}
return false;
}
}
第二题
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n\leq 39n≤39
思路:重点是要了解什么是斐波那契数列。斐波那契数列是从第3项开始,每一项等于前面2项之和。
public class Solution {
public int Fibonacci(int n) {
if(n == 0){
return 0;
}else if(n == 1){
return 1;
}else{
int sum[] = new int[n+1];
sum[0] = 0;
sum[1] = 1;
for(int i = 0; i < n-1; i++){
sum[i+2] = sum[i] + sum[i+1];
}
return sum[n];
}
}
}
第三题
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
[1,2,3,4]
[1,3,2,4]
思路:先用for循环判断奇偶记录下奇数个数,然后用一个新的数组接收,用for循环判断
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/
public int[] reOrderArray (int[] array) {
// write code here
int[] arr=new int[array.length];
int num=0;
for(int a:array){
if((a&1)==1) num++;//奇数
}
int i=0;
for(int a:array){
if((a&1)==1){ //奇数
arr[i++]=a;
}else{
arr[num++]=a;
}
}
return arr;
}
}
重点:for循环那里,num代表奇数的个数,也就是num前面一定是奇数,后面一定是偶数,避免数组越界或者填充到0。
2021/4/8
第1题
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
输出:
[1,2,3,2,2,2,5,4,2]
返回值:
2
思路:
- 暴力破解法。先统计数组长度,确定其一半值,然后用两个for循环嵌套,累计每个数出现的次数,若某个数出现的次数等于或大于半值,则返回该数并退出,否则返回0.
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
//1.暴力破解法
int num = array.length;
int k = 0;
for(int i:array){
int add = 0;
for(int j:array){
if(i == j){
add++;
}
}
if(add>num/2){
k = i;
break;
}else{
k = 0;
}
}
return k;
}
}
- 哈希。先将每一个数存入哈希表作为键,值为1,当有重复键时,值+1.最后判断每一个键,是否有超过半值的,有就输出键,没有返回1
import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
//2.哈希
int len = array.length;
Map<Integer,Integer> map = new HashMap<>();
for(int i : array){
if(!map.keySet().contains(i)){
map.put(i,1);
}else{
map.put(i,map.get(i)+1);
}
}
for(Integer key: map.keySet()){
if(map.get(key) > len/2){
return key;
}
}
return 0;
}
}
第二题
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
输入:
[3,32,321]
返回值:
"321323"
- 思路:设置一个比较函数,若ab>ba,则设置一个之间temp变量,将a,b调换,保证小的再前面。用两个for循环嵌套,比较完之后,再将其转换为字符串拼接。
import java.util.ArrayList;
public class Solution {
public String PrintMinNumber(int [] numbers) {
String str = "";
for(int i=0;i<numbers.length;i++){
for(int j=i;j<numbers.length;j++){
int a = Integer.valueOf(numbers[i]+""+numbers[j]);
int b = Integer.valueOf(numbers[j]+""+numbers[i]);
if(a>b){
int temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
for(int i : numbers){
str += String.valueOf(i);
}
return str;
}
}
第三题【简单】
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * ... * A[n-1],B[n-1] = A[0] * A[1] * ... * A[n-2];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
输入值:
[1,2,3,4,5]
返回值:
[120,60,40,30,24]
- 思路:重点是读懂题目。B[i]没有A[i]的乘阶,所以重点就变成了解决没有A[i]的问题。可以设置一个中间量temp,先将A[i]的值保存到temp中,等for循环结束再恢复数值。
import java.util.ArrayList;
public class Solution {
public int[] multiply(int[] A) {
int len = A.length;
int[] b = new int[len];
for(int i=0;i<len;i++){
int sum = 1;
int temp = A[i];
A[i] = 1;
for(int j=0;j<len;j++){
sum = sum*A[j];
}
b[i] = sum;
A[i] = temp;
}
return b;
}
}
第四题
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
输入:
[2,3,1,0,2,5,3]
返回值:
2或3
- 思路:运用哈希表,先将没出现过的值添加到键里面,当发现有重复的键时返回其键。
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param numbers int整型一维数组
* @return int整型
*/
public int duplicate (int[] numbers) {
// write code here
int len = numbers.length;
Map<Integer,Integer> map = new HashMap<>();
for(int i : numbers){
if(!map.keySet().contains(i)){
map.put(i,1);
}else{
return i;
}
}
return -1;
}
}
2021/4/9
第一题
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
对于50\%50%的数据,size\leq 10^4size≤10
4
对于75\%75%的数据,size\leq 10^5size≤10
5
对于100\%100%的数据,size\leq 2*10^5size≤2∗10
5
输入:
[1,2,3,4,5,6,7,0]
返回值:
7
- 暴力破解法。行不通,时间复杂度为O(n^2)太大,超时。
public class Solution {
public int InversePairs(int [] array) {
int mod = 1000000007;
int len = array.length;
int ret = 0;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if(array[i]>array[j]){
ret += 1;
ret %= mod;
}
}
}
return ret;
}
}
- 归并排序。(不会)