java常见算法

欢迎各位关注我的公众号,会继续更新算法知识与前后端知识

java常见算法_第1张图片

 

1.题目:

给定正整数 n ,我们按任何顺序(包括原始顺序)将数字重新排序,注意其前导数字不能为零。

如果我们可以通过上述方式得到 2 的幂,返回 true;否则,返回 false。

数字排序后进行匹配,不需要对n里的数字进行不断排序,可以判断n与2次方的数(同样长度)进行sort排序后n是否包含在这些被排序后的2次方的数里面

class Solution {
    public boolean reorderedPowerOf2(int n) {

        Set set = new HashSet<>();

        for(int i = 1;i > 0;i <<= 1) {

            set.add(isS(i));
        }

        return set.contains(isS(n));

    }
    public String isS(int x) {

        char[] arr = String.valueOf(x).toCharArray();
        Arrays.sort(arr);
        return new String(arr);
    }
}

2.题目:

我们定义「顺次数」为:每一位上的数字都比前一位上的数字大 1 的整数。

请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表(从小到大排序)。

示例:输出:low = 100, high = 300

输出:[123,234]

暴力枚举超时

dfs:


class Solution {
    public List sequentialDigits(int low, int high) {

        List list = new ArrayList<>();

        for(int i = 1;i <= 9;i++) {
            dfs(list,i,i,low,high);

        }
        //[1234,12345,2345,3456,4567,5678,6789] 这样的例子是错误的,所以需要排序

        Collections.sort(list);
        return list;

    }

    public void dfs(List list,int a,int c,int low,int high) {
        //a=待判断是否符合的数字
        //c=为a准备末尾数字
        //边界条件,数已经大于high
        if(a > high) 
        return;

        //往集合里面添加符合条件的数字
        if(a >= low)
        list.add(a);

        //在符合条件的数字中,9是数字最后一位的最大值
        if(c == 9)
        return;

        dfs(list,a * 10 + c + 1,c+1,low,high);
    }
}

3.题目

把符合下列属性的数组 arr 称为 山脉数组 :arr.length >= 3

存在下标 i(0 < i < arr.length - 1),满足

arr[0] < arr[1] < ... < arr[i - 1] < arr[i]

arr[i] > arr[i + 1] > ... > arr[arr.length - 1]

给出一个整数数组 arr,返回最长山脉子数组的长度。如果不存在山脉子数组,返回 0 。

示例 :

输入:arr = [2,1,4,7,3,2,5]

输出:5

解释:最长的山脉子数组是 [1,4,7,3,2],长度为 5。

pass:一开始的思路是定义2个常量为0,因为只能一次升一次降,而且必须先升才能降,所以必须升的那个常量++才能降,但不实在

class Solution {
    public int longestMountain(int[] arr) {

        int len = arr.length;
        int count = 0;

        for(int i = 1;i < len - 1;i++) {
            //从中间元素开始
            if(arr[i] > arr[i-1] && arr[i] > arr[i+1]) {

                int j = i - 1;
                int x = i + 1;

                while(j > 0) {

                    if(arr[j] > arr[j-1]) {
                        j--;
                    }else {                      
                        break;
                    }
                }
              while(x < len-1) {

                    if(arr[x] > arr[x+1]) {                   
                        x++;
                    }else {

                        break;
                    }
                }

                count = Math.max(count,x-j+1);
            }
        }      
        return count;       
    }
}

4.题目:跳跃游戏1

给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标。

思路:可以不断更新能达到的最远距离,用一个for循环从第一个元素开始便利,前提是能走到。

示例 1:

输入:nums = [2,3,1,1,4]

输出:true

解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。


class Solution {
    public boolean canJump(int[] nums) {

        int len = nums.length;
        //记录能到达的最远的地方
        int max = 0;
        //i记录的是目前在第几个元素
        for(int i = 0;i < len;i++) {
            //只有满足i<=max才合理
            //已知目前能去到的最远地方为max,则max之前的地方都能达到
            if(i <= max) {
            //不断更新最远距离
                max = Math.max(max,i + nums[i]);

                if(max >= len - 1)
                return true;
            }
        }

        return false;
    }
}

5.题目:跳跃游戏2

给你一个非负整数数组 nums ,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

假设你总是可以到达数组的最后一个位置。

思路:我们可以从反方向开始,判断当前位置能否到达终点(从第一个开始遍历,这样能、用最少的步数走最大的距离)。

示例 1:

输入: nums = [2,3,1,1,4]

输出: 2

解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。


class Solution {
    public int jump(int[] nums) {

        int len = nums.length;
        int posi = len - 1;
        int step = 0;

        while(posi > 0) {

            for(int i = 0;i < len;i++) {
            //能去到的(最少的步数走最远的地方)
                if(i + nums[i] >= posi) {

                    step++;
                    //已经能去到终点了,现在只需要去到当前i位置
                    posi = i;
                    break;
                }
            }
        }
        return step;
    }
}

6.题目:

给你一个整数数组 nums 。玩家 1 和玩家 2 基于这个数组设计了一个游戏。

玩家 1 和玩家 2 轮流进行自己的回合,玩家 1 先手。开始时,两个玩家的初始分值都是 0 。每一回合,玩家从数组的任意一端取一个数字(即,nums[0] 或 nums[nums.length - 1]),取到的数字将会从数组中移除(数组长度减 1 )。玩家选中的数字将会加到他的得分上。当数组中没有剩余数字可取时,游戏结束。

如果玩家 1 能成为赢家,返回 true 。如果两个玩家得分相等,同样认为玩家 1 是游戏的赢家,也返回 true 。你可以假设每个玩家的玩法都会使他的分数最大化。

递归

class Solution {
    public boolean PredictTheWinner(int[] nums) {
        int len = nums.length;
        return getBoo(nums,0,len-1,1) >= 0;

    }
    public int getBoo(int[] nums,int left,int right,int player) {

        //递归出口
        if(left == right)
        return player * nums[left];

        //先选左边的情况
        int startLeft = nums[left] * player + getBoo(nums,left + 1,right,-player);
        //先选右边的情况
        int startRight = nums[right] * player + getBoo(nums,left,right - 1,-player);

        if(player == 1){
            //玩家一要最大的
            return Math.max(scoreStart ,scoreEnd );
        }else{
            //玩家二要最小的
            return Math.min(scoreStart ,scoreEnd );
        }
    }
}

你可能感兴趣的:(动态规划,leetcode,算法)