2022-06-21

package com.myapp.jetpackapplication;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {


    public static void main(String[] args) {

//        Scanner scanner = new Scanner(System.in);
//        while (scanner.hasNext()) {
//            int num = scanner.nextInt();
//            int[] array = new int[num];
//            for (int i = 0; i < num; i++) {
//                array[i] = scanner.nextInt();
//            }
//            System.out.println(climbStairs(array));
//        }
        int[] array = {55, 89, 84, 47, 76, 71, 75, 63, 18, 9};
        System.out.println(climbStairs(array));

    }
    private static int minCostClimbingStairs(int[] cost) {
        int[] dp = new int[cost.length + 1];
        for (int i = 2; i <= cost.length; i++) {
            dp[i] = Math.min(dp[i - 2] + cost[i - 2], dp[i - 1] + cost[i - 1]);
        }
        return dp[cost.length];
    }
    /***
     * 给定一个整数数组 cost \cost  ,其中 cost[i]\cost[i]  是从楼梯第i \i 个台阶向上爬需要支付的费用,下标从0开始。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
     * */
    public static int climbStairs(int[] array) {
        int cost = 0;
        if (array.length == 1) {
            return 0;
        }
        if (array.length == 2) {
            return Math.min(array[0], array[1]);
        }
        int step = array.length - 1;
        while (step > 2) {
            int c1 = array[step - 2] + array[step];
            int c2 = array[step - 2] + array[step - 1];
            if (c1 < c2) {
                cost += array[step];
                step -= 2;
            } else {
                cost += array[step - 1];
                step -= 1;
            }

        }
        return cost;
    }

    /**
     * 猴子爬山进阶版  1 2 3 .。。。number步跳   想跳几步跳几步
     **/
    public static int jumpFloorII(int number) {
        int sum = 0;
        if (number == 0) {
            return 0;
        }
        if (number == 1) {
            return 1;
        }
        if (number == 2) {
            return 2;
        }
        sum = sum + 2 * jumpFloorII(number - 1);
        return sum;
    }

    /**
     * 给定一个非负整数 num ,生成杨辉三角的前 num 行。
     * 杨辉三角中,每个数是左上方和右上方的数之和。
     */
    public static int[] getRow(int num) {
        // write code here
        if (num == 0) {
            return new int[]{1};
        }
        if (num == 1) {
            return new int[]{1, 1};
        }
        int[] array = new int[3];
        array[0] = 1;
        array[1] = 2;
        array[2] = 1;
        if (num == 2) {
            return array;
        }
        for (int i = 3; i < num + 1; i++) {
            int[] cur = new int[i + 1];
            int len = i / 2 + 1;
            for (int k = 0; k < len; k++) {
                if (k == 0) {
                    cur[k] = cur[i - k] = 1;
                } else {
                    cur[k] = cur[i - k] = array[k - 1] + array[k];
                }
            }
            array = cur;
        }
        return array;
    }


    /**
     * 给定一个非负整数 num ,生成杨辉三角的前 num 行。
     * 杨辉三角中,每个数是左上方和右上方的数之和。
     */
    public static int[][] generate(int num) {
        // write code here
        int[][] ints = new int[num][];
        for (int i = 0; i < num; i++) {
            int[] array = new int[i + 1];
            if (i == 0) {
                array[i] = 1;
            } else if (i == 1) {
                array[0] = 1;
                array[1] = 1;
            } else {
                int len = i / 2 + 1;
                for (int k = 0; k < len; k++) {
                    if (k == 0) {
                        array[k] = array[i - k] = 1;
                    } else {
                        array[k] = array[i - k] = ints[i - 1][k - 1] + ints[i - 1][k];
                    }
                }
            }
            ints[i] = array;
        }
        return ints;
    }

    /**
     * 给定两个递增数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。
     * 上中位数:假设递增序列长度为n,为第n/2个数
     */
    public static int findMedianinTwoSortedAray(int[] arr1, int[] arr2) {
        if (arr1.length == 1) {
            return Math.min(arr1[0], arr2[0]);
        }

        int left1 = 0;
        int right1 = arr1.length - 1;

        int left2 = 0;
        int right2 = arr2.length - 1;

        while (left1 < right1) {
            //1 先找出两个数组的中间索引位置
            int middle1 = left1 + (right1 - left1) / 2;
            int middle2 = left2 + (right2 - left2) / 2;
            // 当前剩余数组总个数为偶数  索引需要向后动一位 保证两个数组剩余个数相同
            int fillIn = ((right1 - left1) + 1) % 2 == 0 ? 1 : 0;
            if (arr1[middle1] == arr2[middle2]) {
                return arr1[middle1];
            } else if (arr1[middle1] > arr2[middle2]) {
                // arr1剩余的中间位大于array2的剩余中间位 那么中位数只能在 lef1--middle1  middle2 -- right2
                right1 = middle1;
                left2 = middle2 + fillIn;
            } else {
                // arr1剩余的中间位小于array2的剩余中间位 那么中位数只能在 middle1--right1  left2 -- middle2
                left1 = middle1 + fillIn;
                right2 = middle2;
            }
        }
        //最后返回最小的为上中位数
        return Math.min(arr1[left1], arr2[left2]);
    }


    public static int waysToChange(int n) {
        int[] coins = {5, 4, 3, 2, 1};
        int[] res = new int[n + 1];
        res[0] = 1;
        for (int coin : coins) {
            for (int i = coin; i <= n; i++) {
                res[i] = res[i] + res[i - coin];
            }
        }
        return res[n];
    }

    /**
     * 输出所有和为S的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
     */
    public static ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        int l = 1;
        int r = 2;
        int result = 3;
        // sum=9 [2,3,4],[4,5]
        while (l < r) {
            if (result < sum) {
                r++;
                result += r;
            } else if (result > sum) {
                result -= l;
                l++;
            } else {
                ArrayList<Integer> integers = new ArrayList<>();
                for (int i = l; i <= r; i++) {
                    integers.add(i);
                }
                list.add(integers);
                result -= l;
                l++;
            }
        }
        return list;
    }


    /**
     * 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度
     */
    public static int lengthOfLongestSubstring(String s) {
        int l = 0;
        int r = 0;
        int max = 0;
        Set<Character> set = new HashSet<>();
        while (r < s.length()) {
            if (set.contains(s.charAt(r))) {
                set.remove(s.charAt(l));
                l++;
            } else {
                set.add(s.charAt(r));
                r++;
            }
            max = Math.max(max, set.size());
        }
        return max;
    }

    /**
     * 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。
     * 注意:
     * 对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
     * 如果 s 中存在这样的子串,我们保证它是唯一的答案。
     */

    public static String minWindow(String s, String t) {
        int l = 0;
        int r = 0;
        int min = Integer.MAX_VALUE;
        String res = "";
        HashMap<Character, Integer> cur = new HashMap<>();
        HashMap<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            char a = t.charAt(i);
            if (map.containsKey(a)) {
                map.put(a, map.get(a) + 1);
            } else {
                map.put(a, 1);
            }
        }
        while (r < s.length()) {
            char c = s.charAt(r);
            if (cur.containsKey(c)) {
                cur.put(c, cur.get(c) + 1);
            } else {
                cur.put(c, 1);
            }
            while (check(cur, map)) {
                if (r - l < min) {
                    min = r - l + 1;
                    res = s.substring(l, r + 1);
                }
                char ch = s.charAt(l);
                cur.put(ch, cur.get(ch) - 1);
                if (cur.get(ch) == 0) {
                    cur.remove(ch);
                }
                l++;
            }
            r++;
        }
        return res;
    }

    public static boolean check(HashMap<Character, Integer> cur, HashMap<Character, Integer> map) {
        for (char c : map.keySet()) {
            if (!cur.containsKey(c) || cur.get(c) < map.get(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。
     * (注:返回的数组下标从1开始算起,保证target一定可以由数组里面2个数字相加得到)
     */
    public static int[] twoSum(int[] numbers, int target) {
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < numbers.length; i++) {
            if (hashMap.containsKey(target - numbers[i])) {
                return new int[]{hashMap.get(target - numbers[i]) + 1, i + 1};
            } else {
                hashMap.put(numbers[i], i);
            }

        }
        return null;
    }


    /**
     * 数组3个数的最大乘积 最大乘积
     * 数据范围:
     * 10^-4 ≤A[i]≤10^4
     * A 10^4>长度>=3
     *
     * @param A int整型一维数组
     * @return long长整型
     */
    public static long solve(int[] A) {
        // 先排序
        Arrays.sort(A);
        // 3 个数相乘 结果:
        // 1、3个正数 或3个负数 最大的三个数相乘 得到最大积
        // 2、2个正数1个负数  说明数组中只有3个元素 再多一个负数 负负得正 其结果为正数
        // 3、1个正数和2个负数 负负得正 最小的两个负数相乘得到最大积 或者 最大的三个正数相乘得到的积
        int len = A.length;
        long a = A[len - 1];
        long b = A[len - 2];
        long c = A[len - 3];
        long m = A[1];
        long n = A[0];
        return Math.max(a * b * c, a * m * n);
    }

    /**
     * 遍历链表
     */

    public static void traverseLinkedList(ListNode head) {
        if (head == null || head.next == null) {
            return;
        }
        ListNode cur = head;
        while (cur != null) {
            if (cur != null)
                System.out.println(cur.val);
            cur = cur.next;

        }

    }

    /**
     * 反转链表重复
     */
    public static ListNode ReverseList(ListNode head) {
        if (head == null) {
            return null;
        }
        if (head.next == null) {
            return head;
        }

        ListNode reHead = null;
        ListNode cur = head;
        while (cur != null) {
            // 1 先保存当前节点 下一节点
            ListNode next = cur.next;
            // 2 当前节点的 下一个节点指向上一个节点
            cur.next = reHead;
            // 更新反转节点指针 指向当前节点
            reHead = cur;
            // 更新当前节点指针
            cur = next;

        }
        return reHead;
    }


    /**
     * 去除链表重复
     */
    public static ListNode deleteDuplicates(ListNode head) {
        // write code here
        if (head == null) {
            return null;
        }
        ListNode cur = head;
        while (cur.next != null) {
            if (cur.val == cur.next.val) {
                cur.next = cur.next.next;
            } else {
                cur = cur.next;
            }
        }
        return head;
    }

    static class ListNode {
        public ListNode(int v) {
            val = v;
        }

        int val;
        ListNode next = null;
    }

    /***
     * 给出一个有序的整数数组 A 和有序的整数数组 B ,请将数组 B 合并到数组 A 中,变成一个有序的升序数组
     *
     * 数据范围: 0 \le n,m \le 1000≤n,m≤100,|A_i| <=100∣A
     * i
     * 
     *  ∣<=100, |B_i| <= 100∣B
     * i
     * 
     *  ∣<=100
     *
     * 注意:
     * 1.保证 A 数组有足够的空间存放 B 数组的元素, A 和 B 中初始的元素数目分别为 m 和 n,A的数组空间大小为 m+n
     * 2.不要返回合并的数组,将数组 B 的数据合并到 A 里面就好了,且后台会自动将合并后的数组 A 的内容打印出来,所以也不需要自己打印
     * 3. A 数组在[0,m-1]的范围也是有序的
     * */
    public static void merge(int A[], int m, int B[], int n) {
        int a = m - 1;
        int b = n - 1;
        int c = m + n - 1;
        while (c >= 0) {
            if (a == -1) {
                A[c] = B[b];
                b--;
            } else if (b == -1) {
                break;
            } else if (A[a] > B[b]) {
                A[c] = A[a];
                a--;
            } else {
                A[c] = B[b];
                b--;
            }
            c--;
        }
    }


    /**
     * 输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。
     */
    public static int findGreatestSumOfSubArray(int[] array) {
        // 得到当前数组相加结果
        int sum = 0;
        // 子数组的和的最大值
        int max = array[0];

        // sIndex  子数组起始位置 初始值0
        // eIndex 子数组结束位置 初始值0
        for (int i = 0; i < array.length; i++) {
            // 若sum+array[i]> array[i]; 则 sum 的值为数组连续相加结果
            // 若sum+array[i]<array[i] 大 则sum 的值当前array[i]的值 sIndex 位置指向i
            sum = Math.max(sum + array[i], array[i]);
            // max>sum  上一次子数组相加结果+array[i] 比最大值自小 eIndex 位置不变
            // max<sum  上一次子数组相加结果+array[i] 比最大自值大 eIndex 位置指向i
            max = Math.max(sum, max);
        }
        return max;
    }


    /**
     * 给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。
     **/
    public static ArrayList<Integer> spiralOrder(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        //先排除特殊情况
        if (matrix.length == 0) {
            return res;
        }
        //左边界
        int left = 0;
        //右边界
        int right = matrix[0].length - 1;
        //上边界
        int up = 0;
        //下边界
        int down = matrix.length - 1;
        //直到边界重合
        while (left <= right && up <= down) {
            //上边界的从左到右
            for (int i = left; i <= right; i++)
                res.add(matrix[up][i]);
            //上边界向下
            up++;
            if (up > down)
                break;
            //右边界的从上到下
            for (int i = up; i <= down; i++)
                res.add(matrix[i][right]);
            //右边界向左
            right--;
            if (left > right)
                break;
            //下边界的从右到左
            for (int i = right; i >= left; i--)
                res.add(matrix[down][i]);
            //下边界向上
            down--;
            if (up > down)
                break;
            //左边界的从下到上
            for (int i = down; i >= up; i--)
                res.add(matrix[i][left]);
            //左边界向右
            left++;
            if (left > right)
                break;
        }
        return res;
    }


    /**
     * 假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
     * 1.你可以买入一次股票和卖出一次股票,并非每天都可以买入或卖出一次,总共只能买入和卖出一次,且买入必须在卖出的前面的某一天
     * 2.如果不能获取到任何利润,请返回0
     * 3.假设买入卖出均无手续费
     */
    public int maxProfit(int[] prices) {
        // write code here
        int len = prices.length;
        int minPrices = Integer.MAX_VALUE;
        int ans = 0;
        for (int i = 0; i < len; i++) {
            //寻找最低点
            if (prices[i] < minPrices) {
                minPrices = prices[i];
            } else if (prices[i] - minPrices > ans) {
                //更新答案(最大利润)
                ans = prices[i] - minPrices;
            }
        }
        return ans;
    }

    /**
     * 某商店规定:三个空汽水瓶可以换一瓶汽水,允许向老板借空汽水瓶(但是必须要归还)。
     * 小张手上有n个空汽水瓶,她想知道自己最多可以喝到多少瓶汽水。
     **/
    public static int getBottle(int n) {
        if (n < 2) {
            return 0;
        }
        return n >> 1;
    }


    /**
     * 给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。
     * 字符串回文指该字符串正序与其逆序逐字符一致
     * 输入:
     * "absba"
     * 复制
     * 返回值:
     * true
     *
     * @param str string字符串 待判断的字符串
     * @return bool布尔型
     */
    public static boolean judge(String str) {
        if (str.length() == 1) {
            return true;
        }

        String s = new StringBuilder(str).reverse().toString();
        return s.equals(str);
    }

    /**
     * 求出a、b的最大公约数。
     *
     * @param a int
     * @param b int
     * @return int
     */
    public int gcd(int a, int b) {
        if (b > a) {
            int i = b;
            b = a;
            a = i;
        }
        return a % b == 0 ? b : gcd(b, a % b);
    }

}




©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • “ 就在那么一瞬间,突然心酸涌上心头,心都空了,不知所措的年龄什么都不尽人意,失望,疲惫,压抑,煎熬,这就是现在的我 ”
    白茶山阅读 91评论 0 0
  • 手脱皮了粗粗的看上去像个地图!心很沉着,没有太多想法好似看清了人生还在沉静的活着!好似看清楚了人生还在生存着。 昨...
    人生过客艺嫦阅读 131评论 0 0
  • 过好每一天,干好每一件事,总有天会有所收获,对自己没有坏处
    当时少春衫薄阅读 96评论 0 0
  • 一天,妈妈突然说,想让我相亲,当时很是反感,妈妈说是她一个朋友介绍的,去应付一下也行,想想还是去了,见面了,毫无感...
    想无忧无虑阅读 87评论 0 1
  • 2022年6月20曰,王凡 财富能量课作业第28天 ①每日调频 感恩, 我现在感谢什么哪! 感恩我的爱车,好长时侯...
    阿凡哥平凡世界阅读 273评论 2 4