常见leetcode算法

107 阅读8分钟

常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法常见leetcode算法

递归排序

 // 合并两个有序数组

    private static void merge(int[] arr, int left, int mid, int right, int[] temp) {

        int i = left;    // 左序列指针

        int j = mid + 1; // 右序列指针

        int t = 0;       // 临时数组指针

        

        // 比较左右两部分的元素,放入temp数组

        while (i <= mid && j <= right) {

            if (arr[i] <= arr[j]) {

                temp[t++] = arr[i++];

            } else {

                temp[t++] = arr[j++];

            }

        }

        

        // 将左边剩余元素填充进temp中

        while (i <= mid) {

            temp[t++] = arr[i++];

        }

        

        // 将右边剩余元素填充进temp中

        while (j <= right) {

            temp[t++] = arr[j++];

        }

        

        t = 0;

        // 将temp中的元素全部拷贝到原数组中

        while (left <= right) {

            arr[left++] = temp[t++];

        }

    }


public class MergeSortRecursive {

    

    // 主方法

    public static void mergeSort(int[] arr) {

        if (arr == null || arr.length <= 1) {

            return;

        }

        int[] temp = new int[arr.length];

        mergeSort(arr, 0, arr.length - 1, temp);

    }

  


    // 递归排序

    private static void mergeSort(int[] arr, int left, int right, int[] temp) {

        if (left < right) {

            int mid = left + (right - left) / 2;

            // 递归排序左半部分

            mergeSort(arr, left, mid, temp);

            // 递归排序右半部分

            mergeSort(arr, mid + 1, right, temp);

            // 合并两个有序数组

            merge(arr, left, mid, right, temp);

        }

    }


    public static void main(String[] args) {

        int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};

        mergeSort(arr);

        System.out.println("递归归并排序结果:");

        for (int num : arr) {

            System.out.print(num + " ");

        }

    }

}


public class MergeSortIterative {

    

    public static void mergeSort(int[] arr) {

        if (arr == null || arr.length <= 1) {

            return;

        }

        

        int[] temp = new int[arr.length];

        int length = arr.length;

        

        // 初始子数组大小为1,然后依次加倍

        for (int size = 1; size < length; size *= 2) {

            // 遍历数组,合并相邻的子数组

            for (int left = 0; left < length - size; left += 2 * size) {

                int mid = left + size - 1;

                int right = Math.min(left + 2 * size - 1, length - 1);

                merge(arr, left, mid, right, temp);

            }

        }

    }

    public static void main(String[] args) {

        int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};

        mergeSort(arr);

        System.out.println("\n非递归归并排序结果:");

        for (int num : arr) {

            System.out.print(num + " ");

        }

    }

}

归并排序

快速排序

  


public class QuickSort {

  


    public void sort(int[] arr) {

        if (arr == null || arr.length == 0) {

            return;

        }

        quickSort(arr, 0, arr.length - 1);

    }

  


    private void quickSort(int[] arr, int low, int high) {

        if (low < high) {

            int partitionIndex = hoarePartition(arr, low, high);

            quickSort(arr, low, partitionIndex);

            quickSort(arr, partitionIndex + 1, high);

        }

    }

  


    private int hoarePartition(int[] arr, int low, int high) {

        // 选择中间元素作为基准(可改为其他选择方式)

        int pivot = arr[(low + high) / 2];

        int i = low - 1;

        int j = high + 1;

  


        while (true) {

            // 从左向右找第一个大于等于pivot的元素

            do {

                i++;

            } while (arr[i] < pivot);

  


            // 从右向左找第一个小于等于pivot的元素

            do {

                j--;

            } while (arr[j] > pivot);

  


            if (i >= j) {

                return j;

            }

  


            // 交换不符合条件的元素

            swap(arr, i, j);

        }

    }

  


    private void swap(int[] arr, int i, int j) {

        int temp = arr[i];

        arr[i] = arr[j];

        arr[j] = temp;

    }

  


    // 测试代码

    public static void main(String[] args) {

        int[] arr = {10, 7, 8, 9, 1, 5, 3, 2, 4, 6};

        QuickSort qs = new QuickSort();

        qs.sort(arr);

        System.out.println("排序结果:");

        for (int num : arr) {

            System.out.print(num + " ");

        }

    }

}

二分查找方法

1。查到返回,查不到就返回要插入的位置 返回left
2。查某个数字在数组中出现的次数。0.5后0.5 返回left
4。旋转数组(括号,-1还是不加,有死循环啊)

返回要插入的数据:
class Solution {
    public int searchAndInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = (right - left) /2 + left;
            if (target ==nums[mid]) {
             return mid;
            }else if (nums[mid]<target){
                left = mid + 1;
             
            } else {
                  right = mid - 1;
            }
        }
        return left;
    }
}
//最后一个数,或者大于的位置
class Solution {
    public int searchAndInsert(int[] nums, int target+0.5) {
        int n = nums.length;
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = (right - left) /2 + left;
            if (nums[mid]<target){
                left = mid + 1;
            } else {
                  right = mid - 1;
            }
        }
        return left-1;
    }
}
//第一个数,或者大于的位置
class Solution {
    public int searchAndInsert(int[] nums, int target-0.5) {
        int n = nums.length;
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = (right - left) /2 + left;
            if (nums[mid]<target){
                left = mid + 1;
            } else {
                  right = mid - 1;
            }
        }
        return left;
    }
}

//最后一个数,或者大于的位置
class Solution {
    public int searchAndInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = (right - left) /2 + left;
            if (nums[mid]<=target){
                left = mid + 1;
             
            } else {
                  right = mid - 1;
            }
        }
        return right;
    }
}
//第一个数,或者大于的位置
class Solution {
    public int searchAndInsert(int[] nums, int target) {
        int n = nums.length;
        int left = 0, right = n - 1;
        while (left <= right) {
            int mid = (right - left) /2 + left;
            if (nums[mid]=>target){
                right = mid - 1;
             
            } else {
                  left = mid + 1;
            }
        }
        return left;
    }
}

背包问题

背包问题,n种物品,第i个物品体积为weight[i],价值为values[i]
定义  dp[w]  为背包容量为  w  时能获得的最大价值。所有初始化为0
01背包
for (int i = 0; i < n; i++) {
    for (int w = W; w >= weights[i]; w--) {
        // 决策:不选当前物品 或 选当前物品
        dp[w] = Math.max(dp[w], dp[w - weights[i]] + values[i]);
    }
}
完全背包
for (int i = 0; i < n; i++) {
    for (int w = weights[i]; w <= W; w++) {
        // 决策:不选当前物品 或 新增一个当前物品
        dp[w] = Math.max(dp[w], dp[w - weights[i]] + values[i]);
    }


恰好装满问题

public class CompleteKnapsackExactlyFull {
    /**
     * 完全背包恰好装满的最大价值
     * @param W 背包容量
     * @param weights 物品重量数组
     * @param values 物品价值数组
     * @return 最大价值(若无解返回-1)
     */
    public static int knapCompleteExactlyFull(int W, int[] weights, int[] values) {
        int[] dp = new int[W + 1];
        
        // 初始化:除了容量0,其他状态都不可达
        Arrays.fill(dp, Integer.MIN_VALUE);
        dp[0] = 0;
        
        for (int i = 0; i < weights.length; i++) {
            for (int j = weights[i]; j <= W; j++) {
                // 仅当减去当前物品重量的状态可达时,才能更新
                if (dp[j - weights[i]] != Integer.MIN_VALUE) {
                    dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);
                }
            }
        }
        
        return dp[W] < 0 ? -1 : dp[W]; // -1表示无解
    }

    /**
     * 恰好装满的最小物品数量
     * @param W 背包容量
     * @param weights 物品重量数组
     * @return 最小物品数量(若无解返回-1)
     */
    public static int minItemsExactlyFull(int W, int[] weights) {
        int[] dp = new int[W + 1];
        
        // 初始化:除了容量0,其他状态都不可达
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        
        for (int weight : weights) {
            for (int j = weight; j <= W; j++) {
                if (dp[j - weight] != Integer.MAX_VALUE) {
                    dp[j] = Math.min(dp[j], dp[j - weight] + 1);
                }
            }
        }
        
        return dp[W] == Integer.MAX_VALUE ? -1 : dp[W];}      
       
}