leetcode7——容器的最大面积,跳跃数组,合并区间,有序数组转化为平衡二叉树,旋转数组的最小值,快乐数

本文详细解析了LeetCode中的几个经典算法问题,包括求解容器最大面积、跳跃游戏判断能否到达终点、合并重叠区间、有序数组转化为平衡二叉树以及找到旋转数组的最小值。同时,针对每个问题提供了不同的解题思路和示例。
摘要由CSDN通过智能技术生成

leetcode11
题目一:
给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。

在这里插入图片描述
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入: [1,8,6,2,5,4,8,3,7]
输出: 49

解析:两端指针,移动时会将较小的边指针向里移动一位(因为若移动较大的边的指针,面积一定减少)

class Solution {
    public int maxArea(int[] height) {
        int max=0;
        int len=height.length;
        int i=0,j=len-1;
        while(i!=j){
            max=Math.max(Math.min(height[i],height[j])*(j-i),max);
            if(height[i]>height[j])j--;
                else i++;
        }
        return max;
    }
}

leetcode55
题目二:
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。

示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。

示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

解法一:

class Solution {
    public boolean canJump(int[] nums) {
        if(nums.length==0||nums.length==1)return true;
        int nowValue=0;
        int farValue=nums[nowValue];
        int len=nums.length;
        while(nowValue!=farValue&&farValue<len-1){
            int value=farValue;//需要存储前一次farValue的值
            for(int i=nowValue;i<=farValue;i++){
                if(i>=len-1)return true;
                farValue=Math.max(farValue,i+nums[i]);       
            }
            nowValue=farValue;
        }
        if(farValue>=len-1)return true;
        return false;
    }
}

解答二:相同的思路,但是代码简洁

class Solution {
    public boolean canJump(int[] nums) {
        int k=0;
        int len=nums.length;
        for(int i=0;i<len;i++){
            if(i>k)return false;
            k=Math.max(k,i+nums[i]);
        }
        return true;
    }
}

题目三:
leetcode56
给出一个区间的集合,请合并所有重叠的区间。

示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

解析:先将区间按左边界排序。之后只需要判断【区间i的右边界,区间i+1的左边界】的关系即可

class Solution {
    public int[][] merge(int[][] intervals) {
        List<int[]> result=new LinkedList<>();
        if(intervals.length==0||intervals[0].length==0)return result.toArray(new int [0][]);
        Arrays.sort(intervals,(a,b)->a[0]-b[0]);
        int i=0,len=intervals.length;
        while(i<len){
            int left=intervals[i][0];
            int right=intervals[i][1];
            while(i+1<len&&right>=intervals[i+1][0]){
                right=Math.max(right,intervals[i+1][1]);i++;
            }
            result.add(new int[]{left, right});;i++;
        }
        return result.toArray(new int [0][]);   
    }
}

leetcode108
题目四:
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。

本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

示例:

给定有序数组: [-10,-3,0,5,9],

一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树:
0
/
-3 9
/ /
-10 5
解析:因为必须是平衡二叉树,又是有序序列,考虑到取中间节点作为根节点,再递归

class Solution {
    public TreeNode sortedArrayToBST(int[] nums) {
        if(nums.length==0)return null;
        TreeNode root=new TreeNode(nums[nums.length/2]);
        int left[]=Arrays.copyOfRange(nums,0,nums.length/2);
        int right[]=Arrays.copyOfRange(nums,nums.length/2+1,nums.length);
        root.left=sortedArrayToBST(left);
        root.right=sortedArrayToBST(right);
        return root;
    }
}

题目五:
leetcode153

假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
请找出其中最小的元素。
你可以假设数组中不存在重复元素。

示例 1:
输入: [3,4,5,1,2]
输出: 1

示例 2:
输入: [4,5,6,7,0,1,2]
输出: 0

方法一:O(n)

class Solution {
    public int findMin(int[] nums) {
        int i=0;
        int len=nums.length;
        while(i+1<len){
            if(nums[i+1]<nums[i])return nums[i+1];
            i++;
        }
        return nums[0];
    }
}

方法二O(logn)

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

题目六:
leetcode202

编写一个算法来判断一个数是不是“快乐数”。
一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例:
输入: 19
输出: true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

解析:首先快乐数经过处理后得到1,非快乐数会经历循环,如4:都进入 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 的循环中

class Solution {
     private static  int getNums(int n){
        int sum=0;
        while(n!=0){
            int a=n%10;
            sum+=a*a;
            n=n/10;
        }
        return sum;
    }
    public  boolean isHappy(int n) {
        int slowNum=n,fastNum=this.getNums(n);
        while(slowNum!=fastNum){
            slowNum=getNums(slowNum);
            fastNum=getNums(fastNum);
            fastNum=getNums(fastNum);
        }
        return slowNum==1;
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值