数组系列算法
1.斐波那契数列–面试题10
//斐波那契数列(递归求解)
//特征:该数=它的前两个数之和
package com.leetecode.top100.other;
public class Fob {
public static void main(String[] args) {
System.out.println(fob(0));
}
public static int fob(int n){
if(n==0) return 0;
if(n==1) return 1;
return fob(n-1)+fob(n-2);
}
}
2.输出数组中重复的数字–面试3
package com.leetecode.top100.array.duplicatenums;
import java.util.ArrayList;
import java.util.HashSet;
//输出数组中重复的数字
public class DuplicateNums {
public static void main(String[] args) {
int[] arr=new int[]{
2, 3, 1, 0, 2, 5, 3};
duplicateNums(arr);
}
public static void duplicateNums(int[] arr){
if(arr.length==0){
return ;
}
HashSet<Integer> set = new HashSet<>();
ArrayList<Integer> list = new ArrayList<>();
int left=0;
while(left<arr.length){
while(left<arr.length&&set.contains(arr[left])){
//先判断left<arr.length,否则数组会越界
list.add(arr[left]);
left++;
}
if(left<arr.length){
set.add(arr[left]);
left++;
}
}
for(Integer a:list){
System.out.println(a);
}
}
}
3.在二维数组查找某个元素,存在返回true,不存在返回false–面试题4
二维数组中,行的长度arr.length;列的长度arr[0].length
package com.leetecode.top100.array.twodimesionarrayfind;
public class TwoDimesionArrayFind {
public static void main(String[] args) {
int[][] arr=new int[][]{
{
1,2,8,9},{
2,3,9,12},{
4,7,10,13},{
6,8,11,15}};
System.out.println(twoDimensionArrayFind(arr,7));
}
public static boolean twoDimensionArrayFind(int [][]arr,int target){
int row=0;
int col=arr[0].length-1; //二维数组,列的长度arr[0].length
while(row<arr.length&&col>=0){
if(arr[row][col]>target){
//右上角元素>目标元素,当前列排除
col--;
}else if(arr[row][col]<target){
//右上角元素<目标元素,当前行排除
row++;
}else if(arr[row][col]==target){
return true;
}
}
return false;
}
}
4.输出第n个丑数—面试题49
package com.leetecode.top100.array.uglynumber;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
//输出第n个丑数,丑数是=min(当前丑数*2,*3,*5)
//习惯数上把1当做第1个丑
public class UglyNumber {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
System.out.println(uglyNumber(n));
}
public static int uglyNumber(int n){
if(n==0){
//没有丑数
return -1;
}
int[] arr = new int[n];
arr[0]=1;
int multi2=0,multi3=0,multi5=0;
int i=1;
while(i<n){
int min = Math.min(Math.min(arr[multi2] * 2, arr[multi3] * 3), arr[multi5] * 5);
arr[i]=min; //把丑数存起来,用空间换时间
if(arr[multi2]<=min) multi2++;
if(arr[multi3]<=min) multi3++;
if(arr[multi5]<=min) multi5++;
i++;
}
return arr[n-1];
}
}
5.数字在排序数组中出现的次数—面试题53
方法一:
package com.leetecode.top100.array.numoftimes;
//例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}例如数字3出现4次
public class NumOfTimes2 {
public static void main(String[] args) {
int[] arr = new int[]{
1, 2, 3, 3, 3, 3, 4, 4, 5, 5,6};
int firstTarget = firstTarget(arr, 0, arr.length - 1, 100); //寻找最前一个target
int lastTarget = lastTarget(arr, 0, arr.length - 1, 100); //寻找最后一个target
if(firstTarget==-1||lastTarget==-1){
System.out.println(0);
}else{
System.out.println(lastTarget-firstTarget+1);
}
}
public static int firstTarget(int arr[],int left,int right,int target){
int mid=(left+right)/2;
if(left>right){
return -1;
}
if(target>arr[mid]){
return firstTarget(arr,mid+1,right,target);
}else if(target<arr[mid]){
return firstTarget(arr,left,mid-1,target);
}else {
if((mid>0&&arr[mid-1]!=target)||mid==0){
return mid;
}else{
return firstTarget(arr,left,mid-1,target);
}
}
}
public static int lastTarget(int arr[],int left,int right,int target){
int mid=(left+right)/2;
if(left>right){
return -1;
}
if(target>arr[mid]){
return lastTarget(arr,mid+1,right,target);
}else if(target<arr[mid]){
return lastTarget(arr,left,mid-1,target);
}else {
if((mid<arr.length-1&&arr[mid+1]!=target)||mid==arr.length-1){
return mid;
}else{
return lastTarget(arr,mid+1,right,target);
}
}
}
}
方法二:
package com.leetecode.top100.array.numoftimes;
//例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}例如数字3出现4次
public class NumOfTimes {
public static void main(String[] args) {
int[] arr = new int[]{
1, 2, 3, 3, 3, 3, 4,4, 5};
int index = twoSearch(arr, 0, arr.length-1, 8);
int count=0;
if(index!=-1){
count++;
for(int i=0;i<index;++i){
if(arr[i]==arr[index]){
count++;
}
}
for(int i=index+1;i<arr.length;++i){
if(arr[i]==arr[index]){
count++;
}
}
}else{
count=-1;
}
System.out.println(count);
}
public static int twoSearch(int[] arr,int left,int right,int target){
//二分查找
if(left>right){
return -1;
}
int mid=(left+right)/2;
if(target>arr[mid]){
//目标元素大于中间元素
return twoSearch(arr,mid+1,right,target);
}else if(target<arr[mid]){
return twoSearch(arr,left,mid-1,target);
}else {
return mid;
}
}
}
6.给定一个数组和滑动窗口的大小,找出所有滑动窗口里的最大值—面试题59
package com.leetecode.top100.array.windows;
import java.util.ArrayList;
import java.util.List;
//给定一个数组和滑动窗口的大小,找出所有滑动窗口里的最大值
//如:数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,求该滑动窗口的最大值[4, 4, 6, 6, 6, 5]
public class MaxWindows {
public static void main(String[] args) {
int[] arr = {
2,3,4,2,6,2,5,1};
System.out.println(maxWindows(arr,3));
}
public static List<Integer> maxWindows(int[] arr,int n){
List<Integer> list = new ArrayList<>();
if(arr==null||arr.length==0||n==0){
return null;
}else if(arr.length==2){
int max = Math.max(arr[0], arr[1]);
list.add(max);
}else if(arr.length==1){
list.add(arr[0]);return list;
}else{
for(int i=0;i<arr.length-2;++i){