当前位置: 首页 > article >正文

刷题日常(移动零,盛最多水的容器,三数之和,无重复字符的最长子串)

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

 

俩种情况:
1.当nums[i]为0的时候 直接i++

2.当nums[i]不为0的时候 此时 需要跟 nums[j]交换 因为nums[j]一直处于0的位置

并且j++,i++

class Solution {
    public void moveZeroes(int[] nums) {
        int i = 0 , j = 0;
        while( i < nums.length) {
            if(nums[i] == 0) {
                i++;
            } else {
                swap(nums,i++,j++);
            }
        }
    }
    public void swap(int[] nums,int i ,int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp; 
    }
}

盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

 装多少水是由最短边决定的,为什么最短边移动,是因为如果长边移动,那么装的水可能会少,(因为由最短边决定,无论你长边移动后高度增加或者减少,都只能是装水量变少。)不可能会多。而如果移动最短边,那么有可能能够装更多的水。

class Solution {
    public int maxArea(int[] height) {
        int left = 0 ,right = height.length-1, ret=0;
        while(left<right) {
           int m = Math.min(height[left],height[right])*(right-left);
            ret = Math.max(m,ret);
            if(height[left] < height[right]) {
                left++;
            } else{
                right--;
            }
        }
        return ret;
    }
}

 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组

1.先进行排序 要找到三个数字和为0的一组数组 所有先给数组排序 

如果数组首元素大于0 可以直接返回空

2.固定其中某个数字,然后在剩余的数组里面找到和为 -nums[i]的数组 ,就说明找到了

3.细节处理 : 因为数组中可能有重复的数字,所以我们要去“去重”,至于哪些要去重呢?

1)i 一定要去重,跳过重复元素,

2) left 和right 也要去重

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        // 递增
        Arrays.sort(nums);
        // 定义返回的结果
        List<List<Integer>> ret = new ArrayList<>();
        for (int i = 0; i < nums.length;) {
            // 一个数为整数 不可能找到和为0的俩个数组 因为已经排序
            if (nums[i] > 0) {
                break;
            }
            // 定义在i后面的数组区间寻找
            int left = i + 1, right = nums.length - 1;
            // 找-nums[i]
            int k = -nums[i];
            // 开始寻找和为k的一对数组
            while (left < right) {
                if (nums[left] + nums[right] < k) {
                    left++;
                } else if (nums[left] + nums[right] > k) {
                    right--;
                } else {
                    // 说明找到了
                    ret.add(new ArrayList<>(Arrays.asList(nums[i], nums[left], nums[right])));
                    left++;
                    right--;
                    // 去重
                    while (left < right && nums[left] == nums[left - 1]) {
                        left++;
                    }
                    while (left < right && nums[right] == nums[right + 1]) {
                        right--;
                    }
                }

            }
            i++;
            // 去重i
            while (i < nums.length && nums[i] == nums[i - 1] ) {
                i++;
            }
        }
        return ret;
    }
}

无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串的长度

题目分析: 

暴力解法:哈希表+遍历
明显这样写效率低,容易超时

使用一个哈希表 ,L记录无重复字符最长子串的起始 R记录无重复字符最长子串的尾巴

用R去遍历整个数组,每次遍历前判断哈希表是否存在此字符,

如果hash内不存在 直接添加到hash表中,并且计算此时的长度,不断更新最长的

如果hash内存在 重点来了:

一直判断L上的位置是否为存在的字符,如果不是,则一直弹出 直到没有重复的字符 ,然后加入到hash表中。计算此时的长度

class Solution {
    public int lengthOfLongestSubstring(String s) {
        Set<Character> hash = new HashSet<>();
        int right = 0,left = 0 , len=0;
        for(right = 0;right<s.length();right++) {
            char ch = s.charAt(right);
            while(left < right && hash.contains(ch)) {
                hash.remove(s.charAt(left));
                left++;
            }
            hash.add(ch);
            len = Math.max(len,right-left+1);
        }
        return len;
    }
}

24-25 


结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力! 


http://www.kler.cn/a/411055.html

相关文章:

  • 记录两次Unity编辑器和真机表现不符的情况,引用丢失等
  • ffmpeg视频滤镜:提取缩略图-framestep
  • 基于FPGA的2FSK调制-串口收发-带tb仿真文件-实际上板验证成功
  • Delphi ADO组件中的 ADOTable、ADOQurey 无SQL语句实现增、删、改、查
  • 嵌入式的C/C++:深入理解 static、const 与 volatile 的用法与特点
  • 【R语言管理】Pycharm配置R语言及使用Anaconda管理R语言虚拟环境
  • Java 中实现异步的方式
  • IMX 平台UART驱动情景分析:read篇--从硬件驱动到行规程的全链路剖析
  • XG(S)-PON原理
  • 【贪心算法第五弹——300.最长递增子序列】
  • QUICK调试camera-xml解析
  • QT QToolButton控件 全面详解
  • Scala—Collections集合概述
  • goframe框架bug-记录
  • 如何提升编程能力第二篇
  • 关于网络安全攻防知识
  • [CA] 读懂core.cpp -3 Core::decode
  • docker 的各种操作
  • 防御网络攻击的创新策略
  • IP反向追踪技术,了解一下?
  • vim 如何高亮/取消高亮
  • MySQL系列之数据类型(Numeric)
  • 【计算机网络】C/C++实现解析Wireshark离线数据包,附源码
  • Java基础.数组排序(冒泡排序和选择排序)数组与遍历
  • JavaScript HTML DOM 实例
  • windowsC#-在异步任务完成时处理