数组常见面试题

这篇博客涵盖了数组相关的经典面试题,包括寻找重复数、删除重复项、最大子数组和、构建乘积数组、数组排序、查找K大数、两数之和、最长无重复子数组等问题,涉及动态规划、二分查找、排序等多种算法思想。同时,还讨论了矩阵的旋转、斐波那契数列、逆序对和跳跃游戏等挑战。

数组常见面试题

数组中重复的数字

https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/


空间复杂度O(n)
class Solution {
    public int findRepeatNumber(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
       HashSet<Integer> set = new HashSet<>();
        for(int num : nums){
            if(set.contains(num)) {
                return num;
            }
            set.add(num);
        }
        return -1;
    }
}

空间复杂度O1class Solution {
    public int findRepeatNumber(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        for(int i = 0; i < nums.length; i++) {
            for(int j = i + 1; j < nums.length; j++ ) {
                if(nums[i] == nums[j]) {
                    return nums[i];
                }
            }
        }
        return -1;
    }
}

寻找重复数

https://leetcode-cn.com/problems/find-the-duplicate-number/

二分
class Solution {
    public int findDuplicate(int[] nums) {
        if(nums == null || nums.length == 0) return -1;
        int n = nums.length - 1;
        int l = 0, r = n;
        while (l < r) {
            int mid = l + r >> 1;      
            int cnt = 0;
            for (int num : nums) {
                if (num <= mid) {
                    cnt += 1;
                }
            }
            if (cnt > mid) {
            
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return l;
    }
}


快慢指针
class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0;
        int fast = 0;
        slow = nums[slow];
        fast = nums[nums[fast]];
        while(slow != fast){
            slow = nums[slow];
            fast = nums[nums[fast]];
        }
        int pre1 = 0;
        int pre2 = slow;
        while(pre1 != pre2){
            pre1 = nums[pre1];
            pre2 = nums[pre2];
        }
        return pre1;
    }
}

删除有序数组中的重复项I(元素只出现一次)

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/

class Solution {
    public int removeDuplicates(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        int i = 0;
        int j = 1;
        while(j < nums.length) {
            if(nums[j] != nums[i]) {
                nums[i + 1] = nums[j];
                i++;
            }
            j++;
        }
        return i + 1;
    }
}

删除有序数组中的重复项 II(元素最多出现两次)

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array-ii/

class Solution {
    public int removeDuplicates(int[] nums) {
        if(nums.length <= 2) return nums.length;
        
        int index = 2;
        for(int i = 2; i < nums.length; i++){
            if(nums[i] != nums[index-2])
                nums[index++] = nums[i];
        }
        
        return index;
    }
}

连续子数组的最大和

https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        int ret = nums[0];
        for(int i = 1; i < nums.length; i++) {
            nums[i] += Math.max(nums[i - 1], 0);
            ret = Math.max(ret, nums[i]);
        }
        return ret;
    }
}

乘积最大子数组(最大连续数子数组的积)

https://leetcode-cn.com/problems/maximum-product-subarray/

class Solution {
     public int maxProduct(int[] nums) {
        int ret= Integer.MIN_VALUE, imax = 1, imin = 1; //一个保存最大的,一个保存最小的。
        for(int i = 0; i < nums.length; i++){
            if(nums[i] < 0){ 
                int tmp = imax; 
                imax = imin; 
                imin = tmp;
                } 
                //如果数组的数是负数,那么会导致最大的变最小的,最小的变最大的。因此交换两个的值。
            imax = Math.max(imax*nums[i], nums[i]);
            imin = Math.min(imin*nums[i], nums[i]);
            
            ret= Math.max(ret, imax);
        }
        return ret;
    }
}

构建乘积数组

https://leetcode-cn.com/problems/gou-jian-cheng-ji-shu-zu-lcof/

class Solution {
    public int[] constructArr(int[]nums) {
        if(nums == null || nums.length == 0) {
            return new int[0];
        }
        int[] ret = new int[nums.length];
        for(int i = 0, j = 1; i < nums.length; i++) {
            // 先乘左边的数(不包括自己)
            ret[i] = j;
            j *= nums[i];
        }
        for(int i = nums.length - 1, j = 1; i >= 0; i--) {
            // 再乘右边的数(不包括自己)
            ret[i] *= j;
            j *= nums[i];
        }
        return ret;
    }
}

把数组排成最小的数

https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/
在这里插入图片描述

class Solution {
    public String minNumber(int[] nums) {
         String[] strs = new String[nums.length];
        for(int i = 0; i < nums.length; i++) {
            strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(strs, (x, y)-> (x + y).compareTo(y + x));
        StringBuffer ret = new StringBuffer();
        for(String s : strs) {
            ret.append(s);
        }
        return ret.toString();
    }
}

把数组排成最大的数(最大数)

https://www.nowcoder.com/practice/fc897457408f4bbe9d3f87588f497729?tpId=117&&tqId=37835&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public String solve (int[] nums) {
        String[] strs = new String[nums.length];
        for(int i = 0; i < nums.length; i++){
            strs[i] = String.valueOf(nums[i]);
        }
        Arrays.sort(strs, (x, y)-> (y + x).compareTo(x + y));
//         Arrays.sort(strs, new Comparator<String>(){
//             public int compare(String a, String b){
//                 return (b + a).compareTo(a + b);
//             }
//         });
        if(strs[0].equals("0")) {
            return "0";
        }
        StringBuilder ret = new StringBuilder();
        for(int i = 0; i < nums.length; i++){
            ret.append(strs[i]);
        }
        return ret.toString();
    }
}

最小的k个数

https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
        if(arr == null || arr.length == 0 || k == 0) {
            return new int[0];
        }
        PriorityQueue<Integer> bigHeap = new PriorityQueue<>((o1, o2)->(o2 - o1));
        for(int num : arr) {
            if(bigHeap.size() < k) {
                bigHeap.offer(num);
            }else if(bigHeap.peek() > num) {
                bigHeap.poll();
                bigHeap.offer(num);
            }
        }
        int[] ret = new int[k];
        int index = 0;
        while(!bigHeap.isEmpty()) {
            ret[index++] = bigHeap.poll();
        }
        return ret;
    }
}

class Solution {
    public int[] getLeastNumbers(int[] arr, int k) {
            if (k >= arr.length) return arr;
        return quickSort(arr, k, 0, arr.length - 1);
    }
    private int[] quickSort(int[] arr, int k, int l, int r) {
        int i = l, j = r;
        while (i < j) {
            while (i < j && arr[j] >= arr[l]) j--;
            while (i < j && arr[i] <= arr[l]) i++;
            swap(arr, i, j);
        }
        swap(arr, i, l);
        if (i > k) return quickSort(arr, k, l, i - 1);
        if (i < k) return quickSort(arr, k, i + 1, r);
        return Arrays.copyOf(arr, k);
    }
    private void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }
}

数组中第K大的数字

https://leetcode-cn.com/problems/xx4gT2/

class Solution {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> bigHeap = new PriorityQueue<>();
        for(int num : nums) {
            if(bigHeap.size() < k) {
                bigHeap.offer(num);
            }else if(bigHeap.peek() < num) {
                bigHeap.poll();
                bigHeap.offer(num);
            }
        }
        return bigHeap.peek();
    }
}

两数之和

https://leetcode-cn.com/problems/two-sum/

import java.util.*;
public class Solution {
    public int[] twoSum (int[] nums, int target) {
        // write code here
        if(nums == null) {
            return new int[]{0};
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(target - nums[i])) {
                return new int[]{map.get(target - nums[i]) + 1, i + 1};
            }else {
                map.put(nums[i], i);
            }
        }
        return null;
    }
}

三数之和

https://www.nowcoder.com/questionTerminal/345e2ed5f81d4017bbb8cc6055b0b711

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer>> threeSum(int[] nums) {
        ArrayList<ArrayList<Integer>> ret = new ArrayList<>();
        if(nums == null || nums.length == 0) {
            return ret;
        }
        Arrays.sort(nums);
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] > 0) {
                break;
            }
            if(i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            int l = i + 1;
            int r = nums.length - 1;
            while(l < r) {
                int sum = nums[i] + nums[l] + nums[r];
                if(sum == 0) {
                    ArrayList<Integer> tmp = new ArrayList<>();
                    tmp.add(nums[i]);
                    tmp.add(nums[l]);
                    tmp.add(nums[r]);
                    ret.add(tmp);
                    while(l < r && nums[l] == nums[l + 1]) {
                        l++;
                    }
                    l++;
                }else if(sum < 0){
                    l++;
                }else {
                    r--;
                }
            }
        }
        return ret;
    }
}

最长无重复子数组

https://www.nowcoder.com/practice/b56799ebfd684fb394bd315e89324fb4?tpId=117&&tqId=37816&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

import java.util.*;
public class Solution {
    public int maxLength (int[] nums) {
        // write code here
        if(nums == null) {
            return -1;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        int max = 0;
        int left = 0;
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(nums[i])) {
                left = Math.max(left, map.get(nums[i]) + 1);
            }
            map.put(nums[i], i);
            max = Math.max(max, i - left + 1);
        }
       return max;
    }
}

class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 记录字符上一次出现的位置
        int[] last = new int[128];
        for(int i = 0; i < 128; i++) {
            last[i] = -1;
        }
        int n = s.length();

        int res = 0;
        int start = 0; // 窗口开始位置
        for(int i = 0; i < n; i++) {
            int index = s.charAt(i);
            start = Math.max(start, last[index] + 1);
            res   = Math.max(res, i - start + 1);
            last[index] = i;
        }
        return res;
    }
}

最长重复子数组

https://leetcode-cn.com/problems/maximum-length-of-repeated-subarray/
动态规划

class Solution {
    public int findLength(int[] A, int[] B) {
        int n = A.length;
        int m = B.length;
        int max = 0;
        int[][] dp = new int[n + 1][m + 1];
        for (int i=1;i<=n;i++) {
            for (int j=1;j<=m;j++) {
                if (A[i - 1] == B[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = 0;
                }
                max = Math.max(max, dp[i][j]);
            }
        }
        return max;
    }
}

合并两个有序数组(合并排序数组)

[https://leetcode-cn.com/problems/sorted-merge-lcci/](https://leetcode-cn.com/problems/sorted-merge-lcci/)import java.util.*;
public class Solution {
    public void merge(int A[], int m, int B[], int n) {
        int k = m + n;
        k--;
        m--;
        n--;
        while(m >= 0 && n >= 0) {
            if(A[m] >= B[n]) {
                A[k--] = A[m--];
            }else {
                A[k--] = B[n--];
            }
        }
        while(n >= 0) {
            A[k--] = B[n--];
        }
    }
}

合并区间

import java.util.*;
public class Solution {
    public ArrayList<Interval> merge(ArrayList<Interval> interval) {
        ArrayList<Interval> ret = new ArrayList<>();
        if(interval == null || interval.size() == 0) {
            return ret;
        }
        interval.sort((a, b) -> (a.start - b.start));
        ret.add(interval.get(0));
        for(int i = 1; i < interval.size(); i++) {
            int left = interval.get(i).start;
            int right = interval.get(i).end;
            if(ret.get(ret.size() - 1).end < left) {
                ret.add(new Interval(left, right));
            }else {
                ret.get(ret.size() - 1).end = Math.max(ret.get(ret.size() - 1).end, right);
            }
        }
        return ret;
    }
}

顺时针打印矩阵

class Solution {
    public int[] spiralOrder(int[][] nums) {
        if(nums == null || nums.length == 0 || nums[0].length == 0) {
            return new int[0];
        }
        int n = nums.length, m = nums[0].length;
        int[] ret = new int[n * m];
        int index = 0;
        boolean[][] arr = new boolean[n][m];
        int[] dx = {-1,0,1,0};
        int[] dy = {0,1,0,-1};
        int x = 0, y = 0, d = 1;
        for(int i = 0; i < n * m; i++) {
            ret[index++] = nums[x][y];
           
            arr[x][y] = true;
            int a = x + dx[d], b = y + dy[d];
            if(a < 0 || a >= n || b < 0 || b >= m || arr[a][b]) {
                d = (d + 1) % 4;
                a = x + dx[d];
                b = y + dy[d];
            }
            x = a;
            y = b;
        }
        return ret;
    }
}

螺旋矩阵

https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> spiralOrder(int[][] nums) {
        ArrayList<Integer> ret = new ArrayList<>();
        if(nums == null || nums.length == 0 || nums[0].length == 0) {
            return ret;
        }
        int n = nums.length, m = nums[0].length;
        boolean[][] arr = new boolean[n][m];
        int[] dx = {-1,0,1,0};
        int[] dy = {0,1,0,-1};
        int x = 0, y = 0, d = 1;
        for(int i = 0; i < n * m; i++) {
            ret.add(nums[x][y]);
            arr[x][y] = true;
            int a = x + dx[d], b = y + dy[d];
            if(a < 0 || a >= n || b < 0 || b >= m || arr[a][b]) {
                d = (d + 1) % 4;
                a = x + dx[d];
                b = y + dy[d];
            }
            x = a;
            y = b;
        }
        return ret;
    }
}

螺旋矩阵II

https://leetcode-cn.com/problems/spiral-matrix-ii/

class Solution {
    public int[][] generateMatrix(int n) {
         int[][] arr = new int[n][n];
        int c = 1, j = 0;
        while (c <= n * n) {
        
            for (int i = j; i < n - j; i++)
                arr[j][i] = c++;
            for (int i = j + 1; i < n - j; i++)
                arr[i][n - j - 1] = c++;
            for (int i = n - j - 2; i >= j; i--)
                arr[n - j - 1][i] = c++;
            for (int i = n -j - 2; i > j; i--)
                arr[i][j] = c++;

            j++;
        }
        return arr;
    }
}

菲波那切数列

  • 解法一: 递归
public class Solution {
    public int Fibonacci(int n) {
        if(n < 2) return n;
        return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
}
  • 解法二: 迭代
public class Solution {
    public int Fibonacci(int n) {
        if(n < 2) return n;
        int f1 = 0, f2 = 0, f3 = 1;
        for(int i = 2; i <= n; i++) {
            f1 = f2;
            f2 = f3;
            f3 = f1 + f2;
        }
        return f3;
    }
}
  • 解法三:动态规划
class Solution {
    public int fib(int n) {
        if(n < 2) return n;
        int [] arr = new int[n + 1];
            arr[0] = 0;
            arr[1] = 1;
        for (int i = 2; i <= n; i++) {
            arr [i] = arr[i-2] + arr[i-1];
        }
        return arr[n];
    }
}

最长斐波那契数列

https://leetcode-cn.com/problems/Q91FMA/

class Solution {
    public int lenLongestFibSubseq(int[] arr) {
        int n = arr.length;
        Map<Integer,Integer> map=new HashMap<>();
        int[][] dp=new int[n][n];
        int max = 0;
        for(int i = 0; i < n - 1; i++){
            for(int j = i + 1; j < n; j++){
                dp[i][j] = 2;
                if(map.containsKey(arr[j] - arr[i])) {
                    dp[i][j] = dp[map.get(arr[j] - arr[i])][i] + 1;
                }
                max = Math.max(max, dp[i][j]);
            }
            map.put(arr[i], i);
        }
        return max == 2 ? 0 : max;
    }
}

跳台阶

public class Solution {
    public int jumpFloor(int n) {
        if(n < 2) {
            return 1;
        }
        int[] arr = new int[n + 1];
        arr[0] = 1;
        arr[1] = 1;
        for(int i = 2; i <= n; i++) {
            arr[i] = arr[i - 1] + arr[i - 2];
        }
        return arr[n];
    }
}

跳台阶扩展问题

核心思路:
在这里插入图片描述

public class Solution {
    public int jumpFloorII(int target) {
        if(target < 2) {
            return 1;
        }
        int[] arr = new int[target + 1];
        arr[1] = 1;
        for(int i = 2; i <= target; i++) {
            arr[i] = 2 * arr[i - 1];
        }
        return arr[target];
    }
}

调整数组顺序使奇数位于偶数前面(顺序可以改变)

https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/

class Solution {
    public int[] exchange(int[] nums) {
        if(nums == null || nums.length == 0) {
            return new int[]{};
        }
        int l = 0;
        int r = nums.length - 1;
        while(l < r) {
            while(l < r && nums[l] % 2 == 1) {
                l++;
            }
            while(l < r && nums[r] % 2 == 0) {
                r--;
            }
            int tmp = nums[l];
            nums[l] = nums[r];
            nums[r] = tmp;
        }
        return nums;
    }
}

调整数组顺序使奇数位于偶数前面(顺序不可以改变)

https://www.nowcoder.com/practice/ef1f53ef31ca408cada5093c8780f44b?tpId=117&&tqId=37776&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

  • 暴力
import java.util.*;

public class Solution {
    public int[] reOrderArray (int[] array) {
        // write code here
        int index = 0;
        int[] res = new int[array.length];
        for (int i : array) {
            if (i % 2 != 0) {
                res[index] = i;
                index++;
            }
        }
        for (int i : array) {
            if (i % 2 == 0) {
                res[index] = i;
                index++;
            }
        }
    return res;
    }
}


import java.util.*;
public class Solution {
    public int[] reOrderArray (int[] arr) {
        // write code here
        int ji = -1;//记录上一个奇数位置,-1兼容开头偶数情况
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] % 2 == 1) {
                ji += 1;
                //两个奇数间的偶数后移,奇数一道上一个奇数后面
                int tmp = arr[i];
                for (int j = i; j > ji; j--) {
                    arr[j] = arr[j-1];
                }
                arr[ji]=tmp;
            }
        }
        return arr;
    }
}

数组的奇偶排序

https://leetcode-cn.com/problems/sort-array-by-parity/submissions/

class Solution {
    public int[] sortArrayByParity(int[] nums) {
        if(nums == null || nums.length == 0) {
            return new int[0];
        }
        int[] ret = new int[nums.length];
        int i = 0, j = nums.length - 1;
        for(int k = 0; k < nums.length; k++) {
            if(nums[k] % 2 == 0) {
                ret[i++] = nums[k];
            }else {
                ret[j--] = nums[k];
            }
        }
        return ret;
    }
}

class Solution {
    public int[] sortArrayByParity(int[] nums) {
        if(nums == null || nums.length == 0) {
            return new int[]{};
        }
        int l = 0;
        int r = nums.length - 1;
        while(l < r) {
            while(l < r && nums[l] % 2 == 0) {
                l++;
            }
            while(l < r && nums[r] % 2 == 1) {
                r--;
            }
            int tmp = nums[l];
            nums[l] = nums[r];
            nums[r] = tmp;
        }
        return nums;
    }
}

最小矩阵之和(矩阵的最小路径和)

https://www.nowcoder.com/practice/7d21b6be4c6b429bb92d219341c4f8bb?tpId=117&&tqId=37823&&companyId=665&rp=1&ru=/company/home/code/665&qru=/ta/job-code-high/question-ranking

class Solution {
    public int minPathSum(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        int f[][] =new int[n][m];
        f[0][0] = grid[0][0];
        for(int i = 1; i < n;i++){
            f[i][0] = f[i - 1][0] + grid[i][0];
        }
        //第一行只能由左到右
        for(int i = 1; i < m; i++){
            f[0][i] = f[0][i - 1] + grid[0][i];
        }

        //其余点的最优目标 只要比较左边和上面的最优路径权重+该点权重
        for(int i = 1; i < n; i++){
            for(int j = 1; j < m; j++){
                f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + grid[i][j];
            }
        }
        return f[n - 1][m - 1];
    }
}

礼物的最大价值(矩阵的最大值)

class Solution {
    public int maxValue(int[][] arr) {
        int n = arr.length, m = arr[0].length;
        int[][] f = new int[n + 1][m + 1];
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]) + arr[i - 1][j - 1];

            }
        }
        return f[n][m];
    }
}

重建二叉树

import java.util.*;
public class Solution {
    public int preIndex;
    public TreeNode dfs(int[] pre, int[] in, int l, int r) {
        if(l > r) {
            return null;
        }
        TreeNode root = new TreeNode(pre[preIndex]);
        int index = findVal(in, pre[preIndex], l, r);
        preIndex++;
        root.left = dfs(pre, in, l, index - 1);
        root.right = dfs(pre, in, index + 1, r);
        return root;
    }
    public int findVal(int[] in, int key, int l, int r) {
        for(int i = l; i <= r; i++) {
            if(in[i] == key) {
                return i;
            }
        }
        return -1;
    }
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre == null || in == null || pre.length == 0 || in.length == 0) {
            return null;
        }
        return dfs(pre, in, 0, in.length - 1);
    }
}

在两个长度相等的排序数组中找到上中位数

  • 暴力解法
import java.util.*;
public class Solution {
    public int findMedianinTwoSortedAray (int[] arr1, int[] arr2) {
        // write code here
        int index1 = 0, index2 = 0;
        int count = 0;
        int min = 0;
        while(count < arr1.length){
            if(arr1[index1] < arr2[index2]){
                min = arr1[index1++];
                count++;
            }else{
                min = arr2[index2++];
                count++;
            }
        }
        return min;
    }
}
  • 二分
import java.util.*;
public class Solution {
    public int findMedianinTwoSortedAray (int[] arr1, int[] arr2) {
        // write code here
        int l1 = 0,l2 = 0;
        int r1 = arr1.length - 1, r2 = arr2.length - 1;
        int mid1 = 0, mid2 = 0;
        while(l1 < r1){
            mid1 = l1 + r1 >> 1;
            mid2 = l2 + r2 >> 1;
            int offset = (r1 - l1) % 2;
            if(arr1[mid1] == arr2[mid2]){
                return arr1[mid1];
            }else if ((arr1[mid1] > arr2[mid2])){
                r1 = mid1 ;
                l2 = mid2 + offset;
            }else{
                l1 = mid1 + offset;
                r2 = mid2 ;
            }
        }
        return arr1[l1] < arr2[l2] ? arr1[l1] : arr2[l2];
    }
}

数组中的逆序对

public class Solution {
    public int InversePairs(int [] nums) {
         if(nums == null || nums.length == 0) {
            return -1;
        }
        return mergeSort(nums, 0, nums.length - 1);
    }
    public int mergeSort(int[] arr, int l, int r) {
        if(l >= r) {
            return 0;
        }
        int mid = l + r >> 1;
        int ret = mergeSort(arr, l, mid) + mergeSort(arr, mid + 1, r);
          int[] tmp = new int[r - l + 1];
        int k = 0;
        int i = l, j = mid + 1;
        while(i <= mid && j <= r) {
            if(arr[i] <= arr[j]) {
                tmp[k++] = arr[i++];
            }else {
                tmp[k++] = arr[j++];
                ret += mid - i + 1;
            }
        }
        while(i <= mid) {
           tmp[k++] = arr[i++];
        }
        while(j <= r) {
           tmp[k++] = arr[j++];
        }
        for(i = l,j = 0; i <= r; i++, j++) {
            arr[i] = tmp[j];
        }
        return ret;
    }
}
  • 技巧
import java.util.*;


public class Solution {
    public int[] reOrderArray (int[] arr) {
        // write code here
        int ji = -1;//记录上一个奇数位置,-1兼容开头偶数情况
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] % 2 == 1) {
                ji += 1;
                //两个奇数间的偶数后移,奇数一道上一个奇数后面
                int tmp = arr[i];
                for (int j = i; j > ji; j--) {
                    arr[j] = arr[j-1];
                }
                arr[ji]=tmp;
 
            }
        }
        return arr;
    }
}

旋转数组(向后移动k个元素)

import java.util.*;
public class Solution {
     public int[] solve (int n, int m, int[] a) {
        int k = m % n;
        reverse(a, 0, n - 1);
        reverse(a, 0 , k - 1);
        reverse(a, k, n - 1);
        return a;
    }
     
    public void reverse(int[] a,int l,int r){
        while (l < r){
            int tmp = a[l];
            a[l] =a [r];
            a[r] = tmp;
            l++;
            r--;
        }
    }
}

顺时针旋转矩阵(旋转90°)

https://leetcode-cn.com/problems/rotate-matrix-lcci/

import java.util.*;
public class Solution {
    public int[][] rotateMatrix(int[][] arr ,int n) {
        //对角线交换
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                int tmp = arr[i][j];
                arr[i][j] = arr[j][i];
                arr[j][i] = tmp;
            }
        }
        //左右交换
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n / 2; j++) {
                //获得左列对应的右列的值
                int tmp = arr[i][(n - 1) - j];
                arr[i][(n-1) - j] = arr[i][j];
                arr[i][j] = tmp;
            }
        }
        return arr;
    }
}

0~n-1中缺失的数字(二分)

https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/

class Solution {
    public int missingNumber(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        int l = 0;
        int r = nums.length - 1;
        while(l < r) {
            int mid = l + r >> 1;
            if(nums[mid] != mid) {
                r = mid;
            }else {
                l = mid + 1;
            }
        }
        if(nums[l] == l) {
            l++;
        }
        return l;
    }
}

缺失的第一个正整数(未排序数组)

https://leetcode-cn.com/problems/first-missing-positive/

import java.util.*;


public class Solution {
    public int minNumberDisappeared (int[] nums) {
        // write code here
       HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            set.add(nums[i]);
        }
        int k = 1;
        while (set.contains(k)){
            k++;
        }
        return k;
    }
}

数组中数字出现的次数I

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/

class Solution {
    public int[] singleNumbers(int[] nums) {
     if(nums == null || nums.length == 0) {
            return new int[0];
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(nums[i])) {
                map.put(nums[i], map.get(nums[i]) + 1);
            }else {
                map.put(nums[i], 1);
            }
        }
        int[] ret = new int[2];
        int index = 0;
        for(int i = 0; i < nums.length; i++) {
            if(map.get(nums[i]) == 1) {
                ret[index++] = nums[i];
            }
        }
        return ret;
    }
}


class Solution {
    public int[] singleNumbers(int[] nums) {
       int x = 0, y = 0, n = 0, m = 1;
        for(int num : nums)    {
             n ^= num;   // 1. 遍历异或
        }           
           
        while((n & m) == 0)   {
              m <<= 1;  // 2. 循环左移,计算 m
        }            
          
        for(int num: nums) {              // 3. 遍历 nums 分组
            if((num & m) != 0) {
                x ^= num;  // 4. 当 num & m != 0
            }else {
                y ^= num;                // 4. 当 num & m == 0
            }
        }
        return new int[] {x, y};          // 5. 返回出现一次的数字
    }
}

数组中数字出现的次数 II

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/


class Solution {
    public int singleNumber(int[] nums) {
       if(nums == null || nums.length == 0) {
            return -1;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            if(map.containsKey(nums[i])) {
                map.put(nums[i], map.get(nums[i]) + 1);
            }else {
                map.put(nums[i], 1);
            }
        }
        for(int i = 0; i < nums.length; i++) {
            if(map.get(nums[i]) == 1) {
               return nums[i];
            }
        }
        return -1;
    }
}


class Solution {
    public int singleNumber(int[] nums) {
        int[] k = new int[32];
        for (int num : nums) {
            for (int i = 0; i < 32; i++) {
                k[i] += num & 1;
                num >>= 1;
            }
        }
        int ret = 0;
        for (int i = 0; i < 32; i++) {
             ret |= (k[i] % 3) << i;
        }
        return ret;
    }
}

数组的奇偶排序(当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数)

class Solution {
    public int[] sortArrayByParityII(int[] nums) {
        if(nums == null || nums.length == 0) {
            return new int[0];
        }
        int[] ret = new int[nums.length];
        int even = 0, odd = 1;
        for(int i = 0; i < nums.length; i++) {
            if(nums[i] % 2 == 0) {
                ret[even] = nums[i];
                even += 2;
            }else {
                ret[odd] = nums[i];
                odd += 2;
            }
        }
        return ret;
    }
}

数组中出现次数超过一半的数字

https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/


class Solution {
    public int majorityElement(int[] nums) {
        if(nums == null || nums.length == 0) {
            return -1;
        }
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }
}

class Solution {
    public int majorityElement(int[] nums) {
        int val = 0, count = 0;
        for(int x : nums) {
            if(count == 0) {
                val = x;
                count = 1;
            }else {
                if(val == x) {
                    count++;
                }else {
                    count--;
                }
            }
        }
        return val;
    }
}

数组中有些元素出现两次而其他元素出现一次。找到所有出现两次的元素。

https://leetcode-cn.com/problems/find-all-duplicates-in-an-array/

class Solution {
    //输入输出的空间不属于额外空间,可以在输入数组中用数字的正负来表示该位置所对应数字是否已经出现过。遍历输入数组,给对应位置的数字取相反数,如果已经是负数,说明前面已经出现过,直接放入输出数组。
    public List<Integer> findDuplicates(int[] nums) {
         List<Integer> ret = new ArrayList<>();
        for(int i = 0;i < nums.length; i++) {
            int num = Math.abs(nums[i]);
        	if(nums[num-1] < 0) {
        		ret.add(Math.abs(nums[i]));
        	}else {
        		nums[num-1] *= -1;
        	}
        }
        return ret;
    }
}

数组中两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/

class Solution {
    public int[] singleNumbers(int[] nums) {
       int x = 0, y = 0, n = 0, m = 1;
        for(int num : nums)               // 1. 遍历异或
            n ^= num;
        while((n & m) == 0)               // 2. 循环左移,计算 m
            m <<= 1;
        for(int num: nums) {              // 3. 遍历 nums 分组
            if((num & m) != 0) x ^= num;  // 4. 当 num & m != 0
            else y ^= num;                // 4. 当 num & m == 0
        }
        return new int[] {x, y};          // 5. 返回出现一次的数字
    }
}

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字

https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/comments/

class Solution {
    //书上解法: 如果一个数字出现3次,它的二进制每一位也出现的3次。如果把所有的出现三次的数字的二进制表示的每一位都分别加起来,那么每一位都能被3整除。 我们把数组中所有的数字的二进制表示的每一位都加起来。如果某一位能被3整除,那么这一位对只出现一次的那个数的这一肯定为0。如果某一位不能被3整除,那么只出现一次的那个数字的该位置一定为1.
    public int singleNumber(int[] nums) {
     int[] k = new int[32];
        for (int num : nums) {
            for (int i = 0; i < 32; i++) {
                k[i] += num & 1;
                num >>= 1;
            }
        }
        int ret = 0;
        for (int i = 0; i < 32; i++) {
             ret |= (k[i] % 3) << i;
        }
        return ret;
    }
}

下一个排列

https://leetcode-cn.com/problems/next-permutation/

class Solution {
    public void nextPermutation(int[] nums) {
        int i  = nums.length -2;
        while(i>=0 && nums[i]>=nums[i+1]){
            i--;
        }
        //退出循环后就是找到前一位的数比后一位数小
        if(i>=0){
            int j = nums.length-1;
            while(j>=0 && nums[j]<=nums[i]){
                //寻找第一个小于num[i]的数
                j--;
            }
            nums[i] = nums[i] + nums[j];
            nums[j] = nums[i] - nums[j]; //nums[i]
            nums[i] = nums[i] - nums[j];

        }
        int l = i+1;
        int r = nums.length-1;
        while(l<r){
            nums[l] = nums[l]+nums[r];
            nums[r] = nums[l]-nums[r]; //nums[i]
            nums[l] = nums[l] - nums[r];

            l++;
            r--;
        }
    }
}

最长连续序列

https://leetcode-cn.com/problems/longest-consecutive-sequence/

  • set

class Solution {
    public int longestConsecutive(int[] nums) {
        HashSet<Integer> set = new HashSet<Integer>();
        for(int x : nums) {
            set.add(x);
        }   //放入hash表中
        int ret = 0;
        for(int x : set)
        {
            if(!set.contains(x-1))
            {
                int y = x;   //以当前数x向后枚举
                while(set.contains(y + 1))  {
                    y++;
                }
                ret = Math.max(ret, y - x + 1);  //更新答案
            }
        }
        return ret;
    }
}
  • hashset
class Solution {
    public int longestConsecutive(int[] nums) {
        // key表示num,value表示num最远到达的连续右边界
        Map<Integer, Integer> map = new HashMap<>();
        // 初始化每个num的右边界为自己
        for (int num : nums) {
            map.put(num, num);
        }

        int ret = 0;
        for (int num : nums) {
            if (!map.containsKey(num - 1)) {
                int right = map.get(num);
                // 遍历得到最远的右边界
                while (map.containsKey(right + 1)) {
                    right = map.get(right + 1);
                }
                // 更新右边界
                map.put(num, right);
                // 更新答案
                ret = Math.max(ret, right - num + 1);
            }
            
        }
        return ret;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值