zoukankan      html  css  js  c++  java
  • leetcode学习03

    双指针算法

    • 普通双指针:两个指针往同一个方向移动

    • 对撞双指针:两个指针面对面移动

    • 快慢双指针:慢指针+快指针

     

    141环形链表

    给定一个链表,判断链表中是否有环。

    public class Solution {//快慢指针
        public boolean hasCycle(ListNode head) {
            if(head==null){
                return false;
            }
            ListNode slow = head;
            ListNode fast = head;
            while(fast!=null && fast.next!=null){
                fast = fast.next.next;
                slow = slow.next;
                if(slow ==fast){
                    return true;
                }
            }
            return false;
        }
    }

    881救生艇

    第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。

    每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。

    返回载到每一个人所需的最小船数。(保证每个人都能被船载)。

    示例 1:

    输入:people = [1,2], limit = 3 输出:1 解释:1 艘船载 (1, 2)

    class Solution {//对撞指针
        public int numRescueBoats(int[] people, int limit) {
           Arrays.sort(people);
           int i=0;
           int j=people.length-1;
           int res=0;
           while(i<=j){
               if(people[i]+people[j]<=limit){
                   i++;
               }
               j--;
               res++;
           }
              return res;
        }
    }

    二分查找算法

    704二分查找

    给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

    示例 1:

    输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4

    class Solution {
        public int search(int[] nums, int target) {
          if(nums==null || nums.length==0){
              return -1;
          }
          int left=0;
          int right=nums.length-1;
          while(left<=right){
              int mid = left+(right-left)/2;//防止边界越界,超过int范围
              if(nums[mid]==target){
                  return mid;
              }else if(nums[mid]>target){
                  right=mid-1;
              }else{
                  left=mid+1;
              }
          }
          return -1;
        }
    }

    35搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

    你可以假设数组中无重复元素。

    示例 1:

    输入: [1,3,5,6], 5 输出: 2

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

    162寻找峰值

    峰值元素是指其值大于左右相邻值的元素。

    给你一个输入数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

    你可以假设 nums[-1] = nums[n] = -∞ 。

     

    示例 1:

    输入:nums = [1,2,3,1] 输出:2 解释:3 是峰值元素,你的函数应该返回其索引 2。

    示例 2:

    输入:nums = [1,2,1,3,5,6,4] 输出:1 或 5 解释:你的函数可以返回索引 1,其峰值元素为 2; 或者返回索引 5, 其峰值元素为 6。

    class Solution {
        public int findPeakElement(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-l)/2;
                if(nums[mid]>nums[mid+1]){
                    r=mid;
                }else{
                    l=mid+1;
                }
            }
             return l;
        }
    }

    74搜索二维矩阵

    编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:

    每行中的整数从左到右按升序排列。
    每行的第一个整数大于前一行的最后一个整数。

    输入:matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
    输出:true

    class Solution {
        public boolean searchMatrix(int[][] matrix, int target) {
          if(matrix==null || matrix.length==0){
              return false;
          }
          int row = matrix.length;//
          int col = matrix[0].length;//
          int l=0;
          int r=row*col-1;
          while(l<=r){
              int mid = l+(r-l)/2;
              int element = matrix[mid/col][mid%col];
              if(element==target){
                  return true;
              }else if(element>target){
                  r=mid-1;
              }else{
                  l=mid+1;
              }
          }
          return false;
        }
    }

    滑动窗口

    209长度最小的子数组

    给定一个含有 n 个正整数的数组和一个正整数 target 。

    找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

    示例 1:

    输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。

    class Solution {
        public int minSubArrayLen(int target, int[] nums) {
           if(nums==null || nums.length==0){
               return 0 ;
           }
          int i=0;
          int j=0;
          int result=nums.length+1;
          int total=0;
          while(j<nums.length){//窗口的最后一个
              total+=nums[j];
              j++;
              while(total>=target){
                  result=Math.min(result,j-i);
                  total-=nums[i];
                  i++;
              }
          }
            return result==nums.length+1 ? 0:result;
        }
    }

    1456定长子串中元音的最大数目

    给你字符串 s 和整数 k 。

    请返回字符串 s 中长度为 k 的单个子字符串中可能包含的最大元音字母数。

    英文中的 元音字母 为(a, e, i, o, u)。

     

    示例 1:

    输入:s = "abciiidef", k = 3 输出:3 解释:子字符串 "iii" 包含 3 个元音字母。

    class Solution {
        public int maxVowels(String s, int k) {
          if(s==null || s.length()==0 || s.length()<k){
              return 0;
          }
          HashSet<Character> set  = new HashSet<>();
          set.add('a');
          set.add('e');
          set.add('i');
          set.add('o');
          set.add('u');
          int res=0;
          int count=0;
          for(int i=0;i<k;i++){//第一个窗口
              char temp=s.charAt(i);
              if(set.contains(temp)){
                  count++;
              }
          }
          res=Math.max(res,count);
          for(int i=k;i<s.length();i++){
              char out=s.charAt(i-k);
              char in = s.charAt(i);
              if(set.contains(out)){
                  count--;
              }
              if(set.contains(in)){
                  count++;
              }
              res=Math.max(res,count);
          }
          return res;
        }
    }
  • 相关阅读:
    Educational Codeforces Round 58 A,B,C,D,E,G
    Codeforces Round #530 (Div. 2) F (树形dp+线段树)
    Codeforces Round #530 (Div. 2) A,B,C,D
    bzoj 3262: 陌上花开
    bzoj 2653: middle (主席树+二分)
    费马小定理的证明
    分组背包
    二维费用的背包问题
    luoguP1164 小A点菜(背包问题)
    完全背包问题
  • 原文地址:https://www.cnblogs.com/asako/p/14808853.html
Copyright © 2011-2022 走看看