剑指 Offer 66. 构建乘积数组
分析:
由于不能使用除法,所以不能暴力求解,暴力求解大概率也会超时。参考官方题解:由题意可知B[0]为A中除A[0]以外的其它数累乘的结果,实际上就是将A[0]当作1时A的累乘结果。假设A=[1, 2, 3, 4, 5]。考虑这样一个矩阵:
对角线上全为1,那么B[0]实际上就是第0行的累乘。根据对角线将矩阵分为上下三角,分别计算再相乘。
代码:
class Solution {
public:
vector<int> constructArr(vector<int>& a) {
int len = a.size();
if(len == 0) return {};
vector<int> b(len, 1);
b[0] = 1;
int tmp = 1;
for(int i = 1; i < len; i++) {
b[i] = b[i - 1] * a[i - 1];
}
for(int i = len - 2; i >= 0; i--) {
tmp *= a[i + 1];
b[i] *= tmp;
}
return b;
}
};
剑指 Offer 48. 最长不含重复字符的子字符串
分析:
动态规划:设dp[i]表示以第i个字符s[i]结尾的字符串的最优解。边界条件:dp[0] = 1,即当只有一个字符时,最长不含重复字符的子串为本身,长度为1。转移条件:当以s[i]结尾时,向前寻找跟当前字符一致的字符的位置,设该位置为j:如果j < 0,说明i之前没有跟s[i]相同的字符,则dp[i] = dp[i - 1] + 1;如果i - j > dp[i - 1],说明跟s[i]相同的字符在长度为dp[i - 1]的子串的左边,即以s[i - 1]结尾的子串中不含有s[i],则有dp[i] = dp[i - 1] + 1;如果i - j <= dp[i - 1],说明跟s[i]相同的字符就在长度为dp[i - 1]的子串里面,此时dp[i] = i - j(两个位置之间没有相同的字符)。
代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.size() == 0) {
return 0;
}
int n = s.size();
vector<int> dp(n + 1, 0);
dp[0] = 1;
for(int i = 1; i < n; i++) {
int j = i - 1;
for(; j >= 0; j--) {
if(s[j] == s[i]) {
break;
}
}
if(dp[i - 1] < i - j) {
dp[i] = dp[i - 1] + 1;
}else {
dp[i] = i - j;
}
}
return *max_element(dp.begin(), dp.end());
}
};