LeetCode 1711. 大餐计数/NC59 矩阵的最小路径和/NC19 子数组的最大累加和问题/NC4 判断链表中是否有环/NC34 求路径/NC65大数斐波那契数列/NC76用两个栈实现队列(

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 1711. 大餐计数/NC59 矩阵的最小路径和/NC19 子数组的最大累加和问题/NC4 判断链表中是否有环/NC34 求路径/NC65大数斐波那契数列/NC76用两个栈实现队列(相关的知识,希望对你有一定的参考价值。

1711. 大餐计数

2021.7.7 每日一题

题目描述

大餐 是指 恰好包含两道不同餐品 的一餐,其美味程度之和等于 2 的幂。

你可以搭配 任意 两道餐品做一顿大餐。

给你一个整数数组 deliciousness ,其中 deliciousness[i] 是第 i​​​​​​​​​​​​​​ 道餐品的美味程度,返回你可以用数组中的餐品做出的不同 大餐 的数量。结果需要对 109 + 7 取余。

注意,只要餐品下标不同,就可以认为是不同的餐品,即便它们的美味程度相同。

 
示例 1:

输入:deliciousness = [1,3,5,7,9]
输出:4
解释:大餐的美味程度组合为 (1,3) 、(1,7) 、(3,5) 和 (7,9) 。
它们各自的美味程度之和分别为 4 、8 、8 和 16 ,都是 2 的幂。
示例 2:

输入:deliciousness = [1,1,1,3,3,3,7]
输出:15
解释:大餐的美味程度组合为 3 种 (1,1) ,9 种 (1,3) ,和 3 种 (1,7) 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-good-meals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

一看就是典型的竞赛题,和两数之和差不多

class Solution {
    public static final int REMAINDER = 1000000007; 
    public int countPairs(int[] deliciousness) {
        //典型竞赛题
        //哈希表
        int res = 0;
        Map<Integer, Integer> map = new HashMap<>();
        int l = deliciousness.length;
        for(int i = 0; i < l; i++){
            int curr = deliciousness[i];
            for(int j = 0; j < 27; j++){
                int bit = (1 << j);
                if(map.containsKey(bit - curr))
                    res = (res + map.get(bit - curr)) % REMAINDER;
            }
            map.put(curr, map.getOrDefault(curr, 0) + 1);
        }
        return res;
    }
}

NC59 矩阵的最小路径和

题目描述

给定一个 n * m 的矩阵 a,从左上角开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,输出所有的路径中最小的路径和。
示例1
输入:
[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]

返回值:
12

思路

因为只能从左边或者上边到达当前位置,直接动规,需要注意的是,因为我这里创建dp数组的时候,多加了一维,如果不对其进行初始化,会造成不适从左上角开始走的。所以需要对这里进行初始化,使得保证从第一个位置开始出发。

import java.util.*;


public class Solution {
    /**
     * 
     * @param matrix int整型二维数组 the matrix
     * @return int整型
     */
    public int minPathSum (int[][] matrix) {
        // write code here
        //动规
        int m = matrix.length;
        int n = matrix[0].length;
        int[][] dp = new int[m + 1][n + 1];
        Arrays.fill(dp[0], Integer.MAX_VALUE);
        for(int i = 1; i <= m; i++){
            dp[i][0] = Integer.MAX_VALUE;
        }
        dp[0][1] = 0;
        dp[1][0] = 0;
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + matrix[i - 1][j - 1];
            }
        }
        return dp[m][n];
    }
}

NC19 子数组的最大累加和问题

题目描述

给定一个数组arr,返回子数组的最大累加和
例如,arr = [1, -2, 3, 5, -2, 6, -1],所有子数组中,[3, 5, -2, 6]可以累加出最大的和12,所以返回12.
题目保证没有全为负数的数据
[要求]
时间复杂度为O(n)O(n),空间复杂度为O(1)O(1)

示例1
输入:
[1, -2, 3, 5, -2, 6, -1]

返回值:
12

思路

import java.util.*;


public class Solution {
    /**
     * max sum of the subarray
     * @param arr int整型一维数组 the array
     * @return int整型
     */
    public int maxsumofSubarray (int[] arr) {
        // write code here
        //dp[i] = max(dp[i - 1] + arr[i] , arr[i])
        int l = arr.length;
        int max = arr[0];
        for(int i = 1; i < l; i++){
            arr[i] = Math.max(arr[i], arr[i] + arr[i - 1]);
            max = Math.max(max, arr[i]);
        }
        return max;
    }
}

NC4 判断链表中是否有环

题目描述

判断给定的链表中是否有环。如果有环则返回true,否则返回false。
你能给出空间复杂度O(1)的解法么?
输入分为2部分,第一部分为链表,第二部分代表是否有环,然后回组成head头结点传入到函数里面。-1代表无环,其他的数字代表有环,这些参数解释仅仅是为了方便读者自测调试
示例1
输入:
{3,2,0,-4},1
返回值:
true
说明:
第一部分{3,2,0,-4}代表一个链表,第二部分的1表示,-4到位置1,即-4->2存在一个链接,组成传入的head为一个带环的链表 ,返回true  

示例2
输入:
{1},-1
返回值:
false
说明:
第一部分{1}代表一个链表,-1代表无环,组成传入head为一个无环的单链表,返回false 
 
示例3
输入:
{-1,-7,7,-4,19,6,-9,-5,-2,-5},6
返回值:
true

思路

快慢指针

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        //快慢指针
        if(head == null)
            return false;
        ListNode slow = head;
        ListNode fast = head.next;
        while(slow != fast){
            if(fast == null || fast.next == null)
                return false;
            slow = slow.next;
            fast = fast.next.next;
        }
        return true;
    }
}

NC34 求路径

题目描述

一个机器人在m×n大小的地图的左上角(起点)。
机器人每次向下或向右移动。机器人要到达地图的右下角(终点)。
可以有多少种不同的路径从起点走到终点?

在这里插入图片描述

备注:m和n小于等于100,并保证计算结果在int范围内

思路

刚开始想用数学的方法,相当于能走m+n步,然后找m步或者n步的位置。相当于求一个组合数
直接化简以后求阶乘的值,代码如下:

import java.util.*;


public class Solution {
    /**
     * 
     * @param m int整型 
     * @param n int整型 
     * @return int整型
     */
    public int uniquePaths (int m, int n) {
        // write code here
        //求组合数
        int A = m + n - 2;
        int B = n - 1;
        double t = 1.0;
        for(int i = 1; i <= B; i++){
            t = t * (A - B + i) / i;
        }
        return (int)t;
    }

}

还是乖乖动规

import java.util.*;


public class Solution {
    /**
     * 
     * @param m int整型 
     * @param n int整型 
     * @return int整型
     */
    public int uniquePaths (int m, int n) {
        // write code here
        //动态规划可以
        //写个一维的
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                dp[j] = dp[j] + dp[j - 1];
            }
        }
        return dp[n - 1];
    } 
}

NC68 跳台阶

题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

思路

最简单的动规

public class Solution {
    public int jumpFloor(int target) {
        int pre = 1;    //跳0层
        int cur = 1;    //跳1层
        for(int i = 2; i <= target; i++){
            int temp = cur + pre;
            pre = cur;
            cur = temp;
        }
        return cur;
    }
}

NC112 进制转换

题目描述

给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数

思路

进制转换,短除法,注意测试用例里还有负数

import java.util.*;


public class Solution {
    /**
     * 进制转换
     * @param M int整型 给定整数
     * @param N int整型 转换到的进制
     * @return string字符串
     */
    public String solve (int M, int N) {
        // write code here
        boolean flag = true;
        if(M < 0){
            M = -M;
            flag = false;
        }
        StringBuffer sb = new StringBuffer();
        while(M != 0){
            int remainer = M % N;
            M = M / N;
            if(remainer > 9){
                sb.append((char)(remainer - 10 + 'A'));
            }else
                sb.append(remainer + "");
        }
        sb = sb.reverse();
        if(!flag){
            sb.insert(0, "-");
        }
        return sb.toString();
    }
}

NC65 斐波那契数列

题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1)。
n≤39

思路

public class Solution {
    public int Fibonacci(int n) {
        if(n == 0)
            return 0;
        int pre = 0;
        int cur = 1;
        for(int i = 2; i <= n; i++){
            int temp = cur + pre;
            pre = cur;
            cur = temp;
        }
        return cur;
    }
}

如果是大数的斐波那契数列的话,一般题目会给对一个值取模,关于取模的操作如下,需要记一下:
在这里插入图片描述
可以采用矩阵快速幂的方法来对解法进行优化
首先,斐波那契数列写成矩阵的形式如下:
在这里插入图片描述
然后主要是求矩阵的n次方,这个怎么实现呢,可以用矩阵快速幂的方法
在这里插入图片描述
所以计算矩阵的n次方也可以用快速幂的方法
先定义矩阵的乘法。
然后求矩阵的n次幂,定义base初始矩阵,每次base都与自己相乘来更新base
将n与1相与,如果当前位为1,那么就加上当前的base
最后可以得到矩阵n次幂的结果,然后根据所求的序列用矩阵中的值来计算最后的结果

NC76用两个栈实现队列

题目描述

用两个栈来实现一个队列,分别完成在队列尾部插入整数(push)和在队列头部删除整数(pop)的功能。 队列中的元素为int类型。保证操作合法,即保证pop操作时队列内已有元素。

示例:
输入:
["PSH1","PSH2","POP","POP"]
返回:
1,2
解析:
"PSH1":代表将1插入队列尾部
"PSH2":代表将2插入队列尾部
"POP“:代表删除一个元素,先进先出=>返回1
"POP“:代表删除一个元素,先进先出=>返回2

思路

import java.util.Stack;

public class Solution {
    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();
    
    public void push(int node) {
        stack1.push(node);
    }
    
    public int pop() {
        if(!stack2.isEmpty())
            return stack2.pop();
        else{
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
            return stack2.pop();
        }
    }
}

以上是关于LeetCode 1711. 大餐计数/NC59 矩阵的最小路径和/NC19 子数组的最大累加和问题/NC4 判断链表中是否有环/NC34 求路径/NC65大数斐波那契数列/NC76用两个栈实现队列(的主要内容,如果未能解决你的问题,请参考以下文章

1711. 大餐计数

文巾解题 1711. 大餐计数

两数之和再进化--大餐计数(哈希表的利用)

笔试题72. LeetCode OJ (59)

从 SQL 查询中捕获计数

LeetCode 1418. 点菜展示表 / NC103 反转字符串 / NC33 合并有序链表 / NC61两数之和