leetcode算法题解(Java版)-8-动态规划+状态压缩

简介: 这道题有点像链表,二叉树中多了个链表,其实解法也应该往链表上去想,一般考虑用两个指针一个当前的,控制外部循环,一个是移动的,控制内部小循环。二叉树不断往下走,一边走一边从左向右实现同一层节点之间链表的链接

一、树

题目描述

Given a binary tree 
    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set toNULL.
Initially, all next pointers are set toNULL.
Note:
You may only use constant extra space.
You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL

思路

  • 题目的意思可能看文字有点不明白,没关系!看明白它给的两个图就行了,就是图上描绘的意思。
  • 这道题有点像链表,二叉树中多了个链表,其实解法也应该往链表上去想,一般考虑用两个指针一个当前的,控制外部循环,一个是移动的,控制内部小循环。二叉树不断往下走,一边走一边从左向右实现同一层节点之间链表的链接

代码

/**
 * Definition for binary tree with next pointer.
 * public class TreeLinkNode {
 *     int val;
 *     TreeLinkNode left, right, next;
 *     TreeLinkNode(int x) { val = x; }
 * }
 */
public class Solution {
    public void connect(TreeLinkNode root) {
        if(root==null){
            return;
        }
        TreeLinkNode p=root;
        TreeLinkNode q=root;
        while(p.left!=null){
            q=p;
            while(q!=null){
                q.left.next=q.right;
                if(q.next!=null){
                    q.right.next=q.next.left; 
                }
                q=q.next;
            }
            p=p.left;
        }
        return;
    }
}

二、动态规划

题目描述

Given a string S and a string T, count the number of distinct subsequences of T in S.
A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie,"ACE"is a subsequence of"ABCDE"while"AEC"is not).
Here is an example:
S ="rabbbit", T ="rabbit"
Return3.

思路

  • 又是典型的动态规划~~重新的复习了一下:

动态规划:

参考:CSDN

动态规划解题的一般思路:

  • 将原问题分解为子问题:子问题和原问题类似
  • 确定状态:即是dp数组,存储了子问题的状态
  • 确定初始状态(边界)的值:这个需要想一下,但其实一般都是由套路的,比如都是0或者都是1。实在不知道,可以用几个值试一试
  • 写出状态转移方程

动态规划解题的特点:

  • 问题具有最优子结构:如果原问题的最优解也是子问题的最优解。
  • 无后效性:当前的状态之和它之前的某些特定位置的状态有关,和路径等无关,即后来产生的值不会影响前面已经确定的值。

回到题目中来

  • 好了,那么来看这一道题:首先可以分解为子问题,而且子问题的最优解也是原问题的最优解。
  • dpi就是所谓的子问题,也是状态空间,表示S[0~i-1]中包含的T[0~j-1]的subsequences(这个定义看题目)数目。然后具体分析请看代码
  • 推荐在草稿画出dp数组,一边看代码一边填dp。

代码

public class Solution {
    public int numDistinct(String S, String T) {
        int lenS=S.length();
        int lenT=T.length();
        if(lenS==0||lenT==0){
            return 0;
        }
        int row=lenS+1;
        int col=lenT+1;
        int [][] dp=new int [row][col];
        for(int i=1;i<col;i++){
            dp[0][i]=0;
        }
        for(int j=0;j<row;j++){
            dp[j][0]=1;
        }
        for(int i=1;i<row;i++){
            //这里在纸上画字符串数组分析的时候,把字符串的下表可以从“1”开始,便于思维理解
            for(int j=1;j<col;j++){
                if(S.charAt(i-1)==T.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1]+dp[i-1][j];//这里可能稍微难理解,
                    //要记住这一步的目的是解决字符串可以是不连续的,只要满足在原来串中顺序不变即可称为subsequence
                    //结合这个区想这一步为啥这么相加,就能理解了,我是用这个笨方法想的。。。
                }
                else{
                    dp[i][j]=dp[i-1][j];//既然S[i-1]和T[j-1]不一样,那么不妨不要S[i],
                    //可不能也不要T[j]噢,因为我们的目标是找到S中包含T的所有subsequences
                }
            }
        }
        return dp[row-1][col-1];
    }
}

状态压缩+细节优化过的代码
详细见代码注释,动态规划一般都是可以压缩一下状态的。

public class Solution {
    public int numDistinct(String S, String T) {
        int lenS=S.length();
        int lenT=T.length();
        if(lenS==0||lenT==0){
            return 0;
        }
        int col=lenT+1;
        int row=lenS+1;
        int dp[]=new int[col];
        for(int i=0;i<col;i++){
            if(i==0){
                dp[i]=1;
                continue;
            }
            dp[i]=0;
        }
        for(int i=1;i<row;i++){
            for(int j=j=Math.min(i,col-1);j>0;j--){
                //其实这里还能再优化,写成 "j=Math.min(i,col-1)"
                //因为S[0~i]不可能包含长度比他大的T[0~j]
                if(S.charAt(i-1)==T.charAt(j-1)){
                    dp[j]=dp[j-1]+dp[j];
                }
                else{
                    dp[j]=dp[j];
                }
            }
        }
        return dp[col-1];
    }
}
目录
相关文章
|
2月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
428 35
|
2月前
|
存储 算法 搜索推荐
《数据之美》:Java数据结构与算法精要
本系列深入探讨数据结构与算法的核心原理及Java实现,涵盖线性与非线性结构、常用算法分类、复杂度分析及集合框架应用,助你提升程序效率,掌握编程底层逻辑。
|
7月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
323 0
|
2月前
|
存储 人工智能 算法
从零掌握贪心算法Java版:LeetCode 10题实战解析(上)
在算法世界里,有一种思想如同生活中的"见好就收"——每次做出当前看来最优的选择,寄希望于通过局部最优达成全局最优。这种思想就是贪心算法,它以其简洁高效的特点,成为解决最优问题的利器。今天我们就来系统学习贪心算法的核心思想,并通过10道LeetCode经典题目实战演练,带你掌握这种"步步为营"的解题思维。
|
6月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
465 58
|
5月前
|
机器学习/深度学习 算法 Java
Java实现林火蔓延路径算法
记录正在进行的森林防火项目中林火蔓延功能,本篇文章可以较好的实现森林防火蔓延,但还存在很多不足,如:很多参数只能使用默认值,所以蔓延范围仅供参考。(如果底层设备获取的数据充足,那当我没说)。注:因林火蔓延涉及因素太多,如静可燃物载量、矿质阻尼系数等存在估值,所以得出的结果仅供参考。
103 4
|
5月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
211 1
|
4月前
|
运维 监控 算法
基于 Java 滑动窗口算法的局域网内部监控软件流量异常检测技术研究
本文探讨了滑动窗口算法在局域网流量监控中的应用,分析其在实时性、资源控制和多维分析等方面的优势,并提出优化策略,结合Java编程实现高效流量异常检测。
206 0
|
5月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
202 0
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
319 0