草庐IT

LeetCode刷题第一周

noviceprogrammeroo 2023-04-18 原文

数组:内存空间连续,数据类型统一,下标从0开始

二分查找

704

class Solution {
    public int search(int[] nums, int target) {
        // 方法一:暴力解法
        // for(int i = 0; i < nums.length; i++){
        //     if(nums[i] == target){//找到目标值
        //         return i;
        //     }
        // }
        // return -1;
        // 方法二:二分查找(元素有序且无重复元素),使用迭代,执行速度快,但是内存消耗大
        // return binarySearch(nums, target, 0, nums.length-1); 
        // 方法三:二分查找,统一使用左闭右闭区间
        // 上来先处理边界条件
        if(target < nums[0] || target > nums[nums.length - 1]){
            return -1;
        }
        int left = 0;
        int right = nums.length - 1;//右闭区间
        int mid = (left + right) >> 1;
        while(left <= right){//因为取得数组区间左右都是闭的,所以取等号的时候也能满足条件,还不需要退出循环
            if(target == nums[mid]){
                return mid;
            }else if(target < nums[mid]){
                right = mid -1;//往左区间缩
            }else{
                left = mid +1;
            }
            mid = (left + right) >> 1;
        }
        return -1;
    }
    // public int binarySearch(int[] nums, int target, int start, int end){
    //     int mid = (start+end)/2;
    //     int find = -1;
    //     if(start > end){//没有找到
    //         return -1;
    //     }
    //     if(target == nums[mid]){
    //         return mid;
    //     }else if(target < nums[mid]){
    //         find = binarySearch(nums, target, start, mid-1);
    //     }else{
    //         find = binarySearch(nums, target, mid+1, end);
    //     }
    //     return find;
    // }
}

搜索插入位置

35

class Solution {
    public int searchInsert(int[] nums, int target) {
        // 有序数组,考虑用二分查找
        int left = 0;
        int right = nums.length - 1;
        int mid = (left + right) >> 1;
        if(target < nums[left]){
            return left;
        }
        if(target > nums[right]){
            return right + 1;
        }
        while(left <= right){
            if(target == nums[mid]){
                return mid;
            }else if(target < nums[mid]){
                right = mid -1;
            }else{
                left = mid + 1;
            }
            mid = (left + right) >> 1;
        }
        return left;//找不到,返回需要插入的位置
    }
}

在排序数组中查找元素的第一个和最后一个位置

34

class Solution {
    public int[] searchRange(int[] nums, int target) {
        // 非递减说明是升序的,但可以有重复元素
        int[] arr = {-1, -1};
        if(nums.length == 0){
            return arr;
        }
        int left = 0;
        int right = nums.length - 1;
        int mid = (left + right) >> 1;
        if(target < nums[left] || target > nums[right]){
            return arr;//边界值
        }
        int leftPoint;//目标数组的开始位置
        int rightPoint;//目标数组的结束位置
        while(left <= right){
            if(target == nums[mid]){
                leftPoint = mid;
                rightPoint = mid;
                while(leftPoint >= 0 && target == nums[leftPoint]){
                    arr[0] = leftPoint;
                    leftPoint--;//向左寻找重复元素
                }
                while(rightPoint <= (nums.length - 1) && target == nums[rightPoint]){
                    arr[1] = rightPoint;
                    rightPoint++;//向右寻找重复元素
                }
                return arr;//返回找到的目标值的位置
            }else if(target < nums[mid]){
                right = mid - 1;
            }else{
                left = mid + 1;
            }
            mid = (left + right) >> 1;
        }
        return arr;//没有找到
    }
}

69、x的平方根

class Solution {
    public int mySqrt(int x) {
        // 使用二分查找
        int left = 0;
        int right = x;
        int mid = (left + right) / 2;
        while(left <= right){
            if((long)mid * mid < x){
                left = mid + 1;
            }else if((long)mid * mid > x){
                right = mid - 1;
            }else{
                return mid;
            }
            mid  = (left + right) / 2;
        }
        return right;
    }
}

367、有效的完全平方数

class Solution {
    public boolean isPerfectSquare(int num) {
        int left = 0, right = num;
        while(left <= right){
            int mid = (left + right) >> 1;
            if((long) mid * mid == num){
                return true;
            }else if((long) mid * mid < num){
                left = mid + 1;
            }else{
                right = mid - 1;
            }
        }
        return false;
    }
}

移除元素

27

class Solution {
    public int removeElement(int[] nums, int val) {
// 原地移除,所有元素
// 数组内元素可以乱序
        // 方法一:暴力解法,不推荐,时间复杂度O(n^2)
        // int right = nums.length;//目标数组长度,右指针
        // for(int i = 0; i < right; i++){
        //     if(val == nums[i]){
        //         right--;//找到目标数值,目标数长度减一,右指针左移
        //         for(int j = i; j < right; j++){
        //             nums[j] = nums[j + 1];//数组整体左移一位(数组元素不能删除,只能覆盖)
        //         }
        //         i--;//左指针左移
        //     }
        // }
        // return right;
        // 方法二:快慢指针,时间复杂度O(n)
        // int solwPoint = 0;
        // for(int fastPoint = 0; fastPoint < nums.length; fastPoint++){
        //     if(nums[fastPoint] != val){
        //         nums[solwPoint] = nums[fastPoint];
        //         solwPoint++;
        //     }
        // }
        // return solwPoint;
        // 方法三:注意元素的顺序可以改变,使用相向指针,时间复杂度O(n)
        int rightPoint = nums.length - 1;
        int leftPoint = 0;
        while(rightPoint >= 0 && nums[rightPoint] == val){
            rightPoint--;
        }
        while(leftPoint <= rightPoint){
            if(nums[leftPoint] == val){
                nums[leftPoint] = nums[rightPoint--];
            }
            leftPoint++;
            while(rightPoint >= 0 && nums[rightPoint] == val){
                rightPoint--;
            }
        }
        return leftPoint;
    }
}

26、删除排序数组中的重复项

class Solution {
    public int removeDuplicates(int[] nums) {
// 相对顺序一致,所以不能使用相向指针。
// 考虑使用快慢指针
        if(nums.length == 1){
            return 1;
        }
        int slowPoint = 0;
        for(int fastPoint = 1; fastPoint < nums.length; fastPoint++){
            if(nums[slowPoint] != nums[fastPoint]){
                nums[++slowPoint] = nums[fastPoint];
            }
        }
        return slowPoint + 1;
    }
}

283、移动零

class Solution {
    public void moveZeroes(int[] nums) {
// 要保持相对顺序,不能用相向指针
        int slowPoint = 0;
        for(int fastPoint = 0; fastPoint < nums.length; fastPoint++){
            if(nums[fastPoint] != 0){
                nums[slowPoint++] = nums[fastPoint];//所有非零元素移到左边
            }
        }
        for(; slowPoint < nums.length; slowPoint++){
            nums[slowPoint] = 0;//把数组末尾置零
        }
    }
}

844、比较含退格的字符串

class Solution {
    public boolean backspaceCompare(String s, String t) {
        // 从前往后的话不确定下一位是不是"#",当前位需不需要消除,所以采用从后往前的方式
        int countS = 0;//记录s中"#"的数量
        int countT = 0;//记录t中"#"的数量
        int rightS = s.length() - 1;
        int rightT = t.length() - 1;
        while(true){
            while(rightS >= 0){
                if(s.charAt(rightS) == '#'){
                    countS++;
                }else{
                    if(countS > 0){
                        countS--;
                    }else{
                        break;
                    }
                }
                rightS--;
            }
            while(rightT >= 0){
                if(t.charAt(rightT) == '#'){
                countT++;
                }else{
                    if(countT > 0){
                        countT--;
                    }else{
                        break;
                    }
                }
                rightT--;
            }
            if(rightT < 0 || rightS < 0){
                break;
            }
            if(s.charAt(rightS) != t.charAt(rightT)){
                return false;
            }
            rightS--;
            rightT--;
        }
        if(rightS == -1 && rightT == -1){
            return true;
        }
        return false;
    }
}

有序数组的平方

977

class Solution {
    public int[] sortedSquares(int[] nums) {
// 用相向的双指针
        int[] arr = new int[nums.length];
        int index = arr.length - 1;
        int leftPoint = 0;
        int rightPoint = nums.length - 1;
        while(leftPoint <= rightPoint){
            if(Math.pow(nums[leftPoint], 2) > Math.pow(nums[rightPoint], 2)){
                arr[index--] = (int)Math.pow(nums[leftPoint], 2);
                leftPoint++;
            }else{
                arr[index--] = (int)Math.pow(nums[rightPoint], 2);
                rightPoint--;
            }
        }
        return arr;
    }
}

长度最小的子数组

209

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
// 注意是连续子数组
        // 使用滑动窗口,实际上还是双指针
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for(int right = 0; right < nums.length; right++){//for循环固定的是终止位置
            sum += nums[right];
            while(sum >= target){
                result = Math.min(result, right - left + 1);//记录最小的子数组
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

904、水果成篮

class Solution {
    public int totalFruit(int[] fruits) {
// 此题也可以使用滑动窗口
        int maxNumber = 0;
        int left = 0;
        Map<Integer, Integer> map = new HashMap<>();//用哈希表记录被使用的篮子数量,以及每个篮子中的水果数量
        for(int right = 0; right < fruits.length; right++){
            map.put(fruits[right], map.getOrDefault(fruits[right], 0) + 1);//往篮子里面放水果
            while(map.size() > 2){//放进去的水果不符合水果类型
                map.put(fruits[left], map.get(fruits[left]) - 1);
                if(map.get(fruits[left]) == 0){
                    map.remove(fruits[left]);
                }
                left++;
            }
            maxNumber = Math.max(maxNumber, right - left + 1);
        }
        return maxNumber;
    }
}

螺旋矩阵 II

59

class Solution {
    public int[][] generateMatrix(int n) {
        // 方法一:直接按序输出
        int[][] arr = new int[n][n];
         int top = 0;
         int buttom = n - 1;
         int left = 0;
         int right = n - 1;;
         int index = 1;
         while(left <= right && top <= buttom && index <= n*n){
             for(int i = left; i <= right; i++){
                 arr[top][i] = index++;
             }
             top++;
             for(int i = top; i <= buttom; i++){
                 arr[i][right] = index++;
             }
             right--;
             for(int i = right; i >= left; i--){
                 arr[buttom][i] = index++;
             }
             buttom--;
             for(int i = buttom; i >= top; i--){
                 arr[i][left] = index++;
             }
             left++;
         }
         return arr;
    }
}

54

class Solution {
    public List<Integer> spiralOrder(int[][] matrix) {
        int top = 0;
        int buttom = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;
        List<Integer> list = new ArrayList<Integer>();
        while(left <= right && top <= buttom){
            for(int i = left; i <= right; i++){
                if(top <= buttom)
                list.add(matrix[top][i]);
            }
            top++;
            for(int i = top; i <= buttom; i++){
                if(left <= right)
                list.add(matrix[i][right]);
            }
            right--;
            for(int i = right; i >= left; i--){
                if(top <= buttom)
                list.add(matrix[buttom][i]);
            }
            buttom--;
            for(int i = buttom; i >= top; i--){
                if(left <= right)
                list.add(matrix[i][left]);
            }
            left++;
        }
        return list;
    }
}

29 、顺时针打印矩阵

class Solution {
    public int[] spiralOrder(int[][] matrix) {
        if(matrix.length == 0){
            return new int[0];
        }
        int top = 0;
        int buttom = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;
        int[] arr = new int[matrix.length*matrix[0].length];
        int index = 0;
        while(left <= right && top <= buttom){
            for(int i = left; i <= right; i++){
                if(top <= buttom)
                arr[index++] = matrix[top][i];
            }
            top++;
            for(int i = top; i <= buttom; i++){
                if(left <= right)
                arr[index++] = matrix[i][right];
            }
            right--;
            for(int i = right; i >= left; i--){
                if(top <= buttom)
                arr[index++] = matrix[buttom][i];
            }
            buttom--;
            for(int i = buttom; i >= top; i--){
                if(left <= right)
                arr[index++] = matrix[i][left];
            }
            left++;
        }
        return arr;
    }
}

有关LeetCode刷题第一周的更多相关文章

  1. Python 刷Leetcode题库,顺带学英语单词(31) - 2

    ValidPalindromeGivenastring,determineifitisapalindrome,consideringonlyalphanumericcharactersandignoringcases. [#125]Example:"Aman,aplan,acanal:Panama"isapalindrome."raceacar"isnotapalindrome.Haveyouconsiderthatthestringmightbeempty?Thisisagoodquestiontoaskduringaninterview.Forthepurposeofthisproblem

  2. ruby-on-rails - CarrierWave - PDF - 只选择第一页 - 2

    我的Rails应用程序中安装了carrierwave。但是,当用户上传多页pdf时,我只希望应用程序获取文档中的第一页并将其转换为jpeg。这可能吗?用什么命令?这是我的uploader。#encoding:utf-8classImageUploader[200,300]##defscale(width,height)##dosomething#end#Createdifferentversionsofyouruploadedfiles:version:thumbdoprocess:resize_to_fill=>[150,210]process:convert=>:jpgdefful

  3. ruby - 如何跳过 CSV 文件的第一行并将第二行作为标题 - 2

    有没有办法跳过CSV文件的第一行,让第二行作为标题?我有一个CSV文件,第一行是日期,第二行是标题,所以我需要能够在遍历它时跳过第一行。我尝试使用slice但它会将CSV转换为数组,我真的很想将其读取为CSV,以便我可以利用header。 最佳答案 根据您的数据,您可以使用另一种方法和skip_lines-option此示例跳过所有以#开头的行require'csv'CSV.parse(DATA.read,:col_sep=>';',:headers=>true,:skip_lines=>/^#/#Markcomments!)do|

  4. arrays - 在一行中选择数组的第一个和最后一个元素 - 2

    我的任务是从数组中选择最高和最低的数字。我想我很清楚我想做什么,但只是努力以正确的格式访问信息以满足通过标准。defhigh_and_low(numbers)array=numbers.split("").map!{|x|x.to_i}array.sort!{|a,b|ba}putsarray[0,-1]end数字可能看起来像"80917234100",要通过,我需要输出"9234"。我正在尝试putsarray.first.last,但一直无法弄明白。 最佳答案 有Array#minmax完全满足您需要的方法:array=[80,

  5. ruby-on-rails - Ruby 或 Rails 有只将第一个字符大写的方法吗? - 2

    或者好像我必须自己写方法?(保持DHA不变):ruby-1.9.2-p180:001>s='omega-3(DHA)'=>"omega-3(DHA)"ruby-1.9.2-p180:002>s.capitalize=>"Omega-3(dha)"ruby-1.9.2-p180:003>s.titleize=>"Omega3(Dha)"ruby-1.9.2-p180:005>s[0].upcase+s[1..-1]=>"Omega-3(DHA)" 最佳答案 如果我的回答只是垃圾,我深表歉意(我不做ruby)。但我相信我已经为您找到了答

  6. ruby - gsub 删除第一个逗号前的所有内容 - 2

    我有这个字符串:auteur="comtedeFlandreetHainaut,Baudouin,Jacques,Thierry"我想删除第一个逗号之前的所有内容,即在这种情况下保留“Baudouin,Jacques,Thierry”试过这个:nom=auteur.gsub(/.*,/,'')但这会删除最后一个逗号之前的每个逗号,只保留“Thierry”。 最佳答案 auteur.partition(",").last#=>"Baudouin,Jacques,Thierry" 关于rub

  7. ruby-on-rails - Order Hash 并删除第一个键值对 - 2

    我有一个以时间戳为键的哈希。hash={"2016-05-31T22:30:58+02:00"=>{"path"=>"/","method"=>"GET"},"2016-05-31T22:31:23+02:00"=>{"path"=>"/tour","method"=>"GET"},"2016-05-31T22:31:05+02:00"=>{"path"=>"/contact_us","method"=>"GET"}}我订购了这个系列并得到了第一双这样的:hash.sort_by{|k,_|k}.first.first但是我该如何删除它呢?删除方法requiresyou知道key的准确

  8. arrays - 字符串数组中字符串第一部分的总和 - 2

    我有一个字符串数组,我需要从中提取第一个单词,将它们转换为整数并获得它们的总和。示例:["5Apple","5Orange","15Grapes"]预期输出=>25我的尝试:["5","5","15"].map(&:to_i).sum 最佳答案 我从你的问题中找到了答案。["5Apple","5Orange","15Grapes"].map(&:to_i).sum在数组中,如果存在任何整数可转换值,那么它将自动转换为整数。 关于arrays-字符串数组中字符串第一部分的总和,我们在Sta

  9. IDEA使用LeetCode插件 - 2

    前言我们习惯用idea编写、调试代码,在LeetCode上刷题时,如果能够在IDEA编写代码,并且做好代码管理,是一件事半功倍的事情。对于后续复习题目,做笔记也会非常便利。本文目的在于介绍LeetCodeEditor的使用,以及配置工具类,最终目录结构如下:note:放置笔记src:放置代码leetcode.editor.cn:插件LeetCodeEditor自动生成utils:自定义的工具包,可用于自动化输入测试用例,定义题目需要的类(结构体)out:运行测试时自动生成LeetCodeEditorGitHub:https://github.com/shuzijun/leetcode-edit

  10. ruby-on-rails - Rails 3 : Looping through array of objects, 忽略数组中的第一个对象? - 2

    在我看来,我正在尝试显示一个对象表,这是我的代码:CategoriesCBB's">然而这是抛出一个错误说:can'tconvertCapabilityBuildingBlockintoArray关系是正确的,错误来self尝试在此处减去数组的第一个对象的行:有什么方法可以忽略数组中的第一个对象来遍历数组吗?谢谢 最佳答案 尝试使用Array.drop-http://www.ruby-doc.org/core/classes/Array.html#M000294 关于ruby-on-ra

随机推荐