Leetcode: Palindrome Partition I II
思路
1. 第一遍做时就参考别人的, 现在又忘记了 做的时候使用的是二维动态规划, 超时加超内存
2. 只当 string 左部分是回文的时候才有可能减少 cut
3. 一维动规. 令 cuts[i] 表示string[i, string.size()] 所需的切割数, 那么
状态转移方程为 cuts[i] = min(cuts[j]+1) j > i && string[i, j] is palindrome
时间复杂度上仍是 o(n*n), 但更新 cuts 的限制条件比较多了, cuts[i] 更新频率较低
代码:
超时二维动规代码
#include <iostream>
#include <memory.h>
using namespace std; int cuts[1000][1000];
int palindrom[1000][1000];
const int INFS = 0x3f3f3f3f;
class Solution {
public:
int minCut(string s) {
memset(cuts, 0x3f, sizeof(cuts));
memset(palindrom, 0x3f, sizeof(palindrom)); int curcuts = countCuts(s,0,s.size()-1); return curcuts;
}
int countCuts(string &s, int i, int j) {
if(j <= i) return 0; if(isPalindrome(s,i,j))
return (cuts[i][j]=0); if(cuts[i][j] != INFS)
return cuts[i][j]; int curcuts = INFS;
for(int k = i; k < j; k++) {
curcuts = min(curcuts, 1+countCuts(s,i,k)+countCuts(s,k+1,j));
}
return (cuts[i][j]=curcuts);
} bool isPalindrome(string &s, int i, int j) {
if(palindrom[i][j] == 1)
return true;
if(j <= i)
return (palindrom[i][j] = true);
if(palindrom[i][j] == 0)
return false;
return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));
}
}; int main() {
string str = "apjesgpsxoeiokmqmfgvjslcjukbqxpsobyhjpbgdfruqdkeiszrlmtwgfxyfostpqczidfljwfbbrflkgdvtytbgqalguewnhvvmcgxboycffopmtmhtfizxkmeftcucxpobxmelmjtuzigsxnncxpaibgpuijwhankxbplpyejxmrrjgeoevqozwdtgospohznkoyzocjlracchjqnggbfeebmuvbicbvmpuleywrpzwsihivnrwtxcukwplgtobhgxukwrdlszfaiqxwjvrgxnsveedxseeyeykarqnjrtlaliyudpacctzizcftjlunlgnfwcqqxcqikocqffsjyurzwysfjmswvhbrmshjuzsgpwyubtfbnwajuvrfhlccvfwhxfqthkcwhatktymgxostjlztwdxritygbrbibdgkezvzajizxasjnrcjwzdfvdnwwqeyumkamhzoqhnqjfzwzbixclcxqrtniznemxeahfozp";
cout << str.size() << endl;
cout << (new Solution())->minCut(str) << endl;
return 0;
}
优化后的一维动规
#include <iostream>
#include <memory.h>
using namespace std; int cuts[1500];
int palindrom[1500][1500];
const int INFS = 0x3f3f3f3f;
class Solution {
public:
int minCut(string s) {
memset(cuts, 0x3f, sizeof(cuts));
memset(palindrom, 0x3f, sizeof(palindrom)); int curcuts = countCuts(s,0,s.size()-1); return curcuts;
}
int countCuts(string &s, int i, int j) {
if(j <= i) return 0; if(isPalindrome(s,i,j))
return 0; if(cuts[i] != INFS)
return cuts[i]; int curcuts = INFS; for(int k = i; k < j; k++) {
if(isPalindrome(s,i,k))
curcuts = min(curcuts, 1+countCuts(s,k+1,j));
}
return (cuts[i]=curcuts);
} bool isPalindrome(string &s, int i, int j) {
if(palindrom[i][j] == 1)
return true;
if(j <= i)
return (palindrom[i][j] = true);
if(palindrom[i][j] == 0)
return false;
return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));
}
}; int main() {
string str = "bb";
cout << str.size() << endl;
cout << (new Solution())->minCut(str) << endl;
return 0;
}
I
第一题用动态规划也是可以做的, 不过会比较麻烦(与Word Break类似)
这里用 dfs 加打印路径, 比较直观
int palindrom[1500][1500];
vector<vector<string> > res;
class Solution {
public:
vector<vector<string>> partition(string s) {
res.clear();
memset(palindrom, 0x3f, sizeof(palindrom));
vector<string> tmp;
dfs(s, tmp, 0);
return res; }
bool isPalindrome(string &s, int i, int j) {
if(palindrom[i][j] == 1)
return true;
if(j <= i)
return (palindrom[i][j] = true);
if(palindrom[i][j] == 0)
return false;
return (palindrom[i][j] = (s[i]==s[j] && isPalindrome(s,i+1,j-1)));
}
void dfs(string &s, vector<string> cur_vec, int depth) {
if(depth == s.size()) {
res.push_back(cur_vec);
return;
}
for(int i = depth; i < s.size(); i ++) {
if(isPalindrome(s, depth,i)) {
cur_vec.push_back(s.substr(depth,i-depth+1));
dfs(s, cur_vec, i+1);
cur_vec.pop_back();
}
}
}
};
Leetcode: Palindrome Partition I II的更多相关文章
- LeetCode: Palindrome Partition
LeetCode: Palindrome Partition Given a string s, partition s such that every substring of the partit ...
- [Leetcode] palindrome partition ii 回文分区
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- [LeetCode] Palindrome Permutation I & II
Palindrome Permutation Given a string, determine if a permutation of the string could form a palindr ...
- LeetCode:Palindrome Partitioning,Palindrome Partitioning II
LeetCode:Palindrome Partitioning 题目如下:(把一个字符串划分成几个回文子串,枚举所有可能的划分) Given a string s, partition s such ...
- [LeetCode] Palindrome Partitioning II 解题笔记
Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...
- [LeetCode] Palindrome Permutation II 回文全排列之二
Given a string s, return all the palindromic permutations (without duplicates) of it. Return an empt ...
- Palindrome Partitioning I & II
Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...
- LeetCode: Palindrome 回文相关题目
LeetCode: Palindrome 回文相关题目汇总 LeetCode: Palindrome Partitioning 解题报告 LeetCode: Palindrome Partitioni ...
- LeetCode Single Number I / II / III
[1]LeetCode 136 Single Number 题意:奇数个数,其中除了一个数只出现一次外,其他数都是成对出现,比如1,2,2,3,3...,求出该单个数. 解法:容易想到异或的性质,两个 ...
随机推荐
- JS 校验,检测,验证,判断函数集合
http://jc-dreaming.iteye.com/blog/754690 /** *判断对象是否为空 *Check whether string s is empty. */ funct ...
- Java Persistence with MyBatis 小结2
MyBatis 最关键的组成部分是 SqlSessionFactory,我们可以从中获取 SqlSession,并执行映射的 SQL 语句.SqlSessionFactory 对象可以通过基于 XML ...
- C#如何判断操作系统位数是32位还是64位
方法一: 对于C#来说,调用WMI是一种简单易行的方式.我们可以用Win32_Processor类里面的AddressWidth属性来表示系统的位宽.AddressWidth的值受CPU和操作系统的双 ...
- Netty的ByteBuf
https://blog.csdn.net/thinking_fioa/article/details/80795673 netty的ByteBuf知识点
- windows 添加打印机
控制面板---->硬件和声音---->设备和打印机--->点击添加打印机 最后安驱动(选择通用) OK!
- Ununtu 15.04 安装MySql(Django连接Mysql)
本文介绍Ubuntu 15.04下安装MySQL ubuntu 15.04安装mysql django项目连接mysql 一.安装数据库 1.sudo apt-get install mysql-se ...
- 高效学习Oracle的方法论
Oracle的很多经验并不是来自工业环境.很多问题和经验都可以从自己的测试里积累 实验要做,但也要想! 那思维的起点是什么? 以下是我的看法.或者有些不合理: ...
- lua工具库penlight--09技术选择
模块化和粒度 在理想的世界,一个程序应该只加载它需要的库.Penlight需要额外100 Kb 的字节码来工作.它是简单但却乏味要加载你需要什么: local data = require 'pl.d ...
- Linux 新增一个用户命令 adduser
这几天新增用户老是会用 useradd , 这条命令比较复杂,记录 adduser 这条超级简单的命令. Full name 最后和用户差不多,不然登录的时候不好辨别 附: 新增用户无法 sudo 请 ...
- [gpio]Linux GPIO简单使用方式1-sysfs
转自:http://blog.csdn.net/drivermonkey/article/details/20132241 1.1.References 1.2.GPIO Usage from a L ...