zoukankan      html  css  js  c++  java
  • 算法-Leetcode几个双指针问题

    1.搜索插入位置

    https://leetcode-cn.com/problems/search-insert-position/

    class Solution {
        public int searchInsert(int[] nums, int target) {
            int left=0,right=nums.length-1;
            while(left<=right){
                int mid=(left+right)/2;
                if(nums[mid]<target){
                    left=mid+1;
                }else if(nums[mid]>target){
                    right=mid-1;
                }else{
                    return mid;
                }
            }
            return left;
        }
    }
    

    2.搜索二维矩阵

    https://leetcode-cn.com/problems/search-a-2d-matrix/

    public boolean searchMatrix(int[][] matrix, int target) {
        if(matrix.length == 0)
            return false;
        int row = 0, col = matrix[0].length-1;
        while(row < matrix.length && col >= 0){
            if(matrix[row][col] < target)
                row++;
            else if(matrix[row][col] > target)
                col--;
            else
                return true;
        }
        return false;
    }
    

    3.删除排序数组重复项

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

    public int removeDuplicates(int[] nums) {
            // 使用双指针
            if(nums==null || nums.length == 1){
                return nums.length;
            }
            int i = 0,j =1;
            while(j<nums.length){
                if(nums[i]==nums[j]){
                    j++;
                }else{
                    i++;
                    nums[i]=nums[j];
                    j++;
                }
            }
            return i+1;
        }
    

    4.链表的中间节点

    https://leetcode-cn.com/problems/middle-of-the-linked-list/

    public ListNode middleNode(ListNode head) {
            ListNode p = head, q = head;
            while (q != null && q.next != null) {
                q = q.next.next;
                p = p.next;
            }
            return p;
    }
    

    5.爱生气的书店老板

    https://leetcode-cn.com/problems/grumpy-bookstore-owner/

    /*
    首先 找到不改变的时候客人就满意的数量和 同时更新数组
    这样问题就转变为 求数组指定长度最大和的问题
    时间复杂度 O(n) 空间复杂度为O(1)
    */
    class Solution {
        public int maxSatisfied(int[] customers, int[] grumpy, int x) {
            int sum = 0, len = customers.length;
            for (int i = 0; i < len; i++) {
                if (grumpy[i] == 0){
                    sum += customers[i];
                    customers[i] = 0;
                } 
            }
            int num = customers[0];
            int maxval = customers[0];
            for (int i = 1; i < len; i++){
                if (i < x) num = num + customers[i];
                else num = num + customers[i] - customers[i - x];
                maxval = Math.max(maxval, num);
            }
            
            return (sum + maxval);
        }
    }
    

    6.滑动窗口最大值

    https://leetcode-cn.com/problems/sliding-window-maximum/

    /*
      思路: 遍历数组 L R 为滑窗左右边界 只增不减
            双向队列保存当前窗口中最大的值的数组下标 双向队列中的数从大到小排序,
            新进来的数如果大于等于队列中的数 则将这些数弹出 再添加
            当R-L+1=k 时 滑窗大小确定 每次R前进一步L也前进一步 保证此时滑窗中最大值的
            数组下标在[L,R]中,并将当前最大值记录
      举例: nums[1,3,-1,-3,5,3,6,7] k=3
         1:L=0,R=0,队列【0】 R-L+1 < k
                队列代表值【1】
         2: L=0,R=1, 队列【1】 R-L+1 < k
                队列代表值【3】
         解释:当前数为3 队列中的数为【1】 要保证队列中的数从大到小 弹出1 加入3
              但队列中保存的是值对应的数组下标 所以队列为【1】 窗口长度为2 不添加记录
         3: L=0,R=2, 队列【1,2】 R-L+1 = k ,result={3}
                队列代表值【3,-1】
         解释:当前数为-1 队列中的数为【3】 比队列尾值小 直接加入 队列为【3,-1】
              窗口长度为3 添加记录记录为队首元素对应的值 result[0]=3
         4: L=1,R=3, 队列【1,2,3】 R-L+1 = k ,result={3,3}
                队列代表值【3,-1,-3】
         解释:当前数为-3 队列中的数为【3,-1】 比队列尾值小 直接加入 队列为【3,-1,-3】
              窗口长度为4 要保证窗口大小为3 L+1=1 此时队首元素下标为1 没有失效
              添加记录记录为队首元素对应的值 result[1]=3
         5: L=2,R=4, 队列【4】 R-L+1 = k ,result={3,3,5}
                队列代表值【5】
         解释:当前数为5 队列中的数为【3,-1,-3】 保证从大到小 依次弹出添加 队列为【5】
              窗口长度为4 要保证窗口大小为3 L+1=2 此时队首元素下标为4 没有失效
              添加记录记录为队首元素对应的值 result[2]=5
        依次类推 如果队首元素小于L说明此时值失效 需要弹出
    */
    class Solution {
        public int[] maxSlidingWindow(int[] nums, int k) {
            if(nums==null||nums.length<2) return nums;
            // 双向队列 保存当前窗口最大值的数组位置 保证队列中数组位置的数按从大到小排序
            LinkedList<Integer> list = new LinkedList();
            // 结果数组
            int[] result = new int[nums.length-k+1];
            for(int i=0;i<nums.length;i++){
                // 保证从大到小 如果前面数小 弹出
                while(!list.isEmpty()&&nums[list.peekLast()]<=nums[i]){
                    list.pollLast();
                }
                // 添加当前值对应的数组下标
                list.addLast(i);
                // 初始化窗口 等到窗口长度为k时 下次移动在删除过期数值
                if(list.peek()<=i-k){
                    list.poll();   
                } 
                // 窗口长度为k时 再保存当前窗口中最大值
                if(i-k+1>=0){
                    result[i-k+1] = nums[list.peek()];
                }
            }
            return result;
        }
    }
    

    吴邪,小三爷,混迹于后台,大数据,人工智能领域的小菜鸟。
    更多请关注
    file

  • 相关阅读:
    IEnumerable<T>转DataTable的几种方法
    关于IAsyncResult接口的CompletedSynchronously属性
    为WCF增加UDP绑定(储备篇)
    WPF自定义集合控件概述与遇到的问题
    WPF嵌套模板引发的血案
    为WCF增加UDP绑定(实践篇)
    Uva 10557 XYZZY(DFS+BFS)
    Uva 572 Oil Deposits(DFS)
    Uva 532 Dungeon Master(三维迷宫)
    Uva 10004 Bicoloring
  • 原文地址:https://www.cnblogs.com/hulichao/p/14290805.html
Copyright © 2011-2022 走看看