判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
双指针
class Solution {
public:
bool isPalindrome(int x) {
string str = to_string(x);
//双指针
int i = 0;
int j = str.size() - 1;
while (i <= j) {
if (str[i] != str[j]) {
return false;
}
i++;
j--;
}
return true;
}
};
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
示例 1:输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:输入:
s = "mississippi"
p = "mis*is*p*."
输出: false来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/regular-expression-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
动态规划
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
//处理p为空字符串的情况
if (n == 0) {
if (m == 0) {
return true;
}
return false;
}
//处理*前面没有其他符号的情况:非法
if (p[0] == '*') {
return false;
}
vector> dp(s.size() + 1, vector(p.size() + 1, false));
dp[0][0] = true;
s = ' ' + s;
p = ' ' + p;
//处理p[j - 1] ='*',空的情况,也就是p和空字符串匹配的情况
for (int j = 2;j <= n; j++) {
if (p[j] == '*') {
dp[0][j] = dp[0][j - 2];
}
}
//处理普通情况
for (int i = 1; i <= m; i++) {
for (int j = 1;j <= n; j++) {
//当p[j - 1]为字符的情况
if (p[j] == s[i]) {
dp[i][j] = dp[i -1][j - 1];
}
//当p[j - 1]为'.'的情况
else if (p[j] == '.') {
dp[i][j] = dp[i - 1][j- 1];
}
else if (p[j] == '*') {
if(p[j - 1] == '.' || p[j - 1] == s[i]){
dp[i][j] = dp[i - 1][j] || dp[i][j - 1] || dp[i][j - 2];
}else{
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[m][n];
}
};
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例:
输入:[1,8,6,2,5,4,8,3,7]
输出:49来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/container-with-most-water
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1、暴力法
2、双指针法(移动两者中较大者)
class Solution {
public:
int maxArea(vector& height) {
//1、暴力法(超过时间限制)
/*int max = INT_MIN;
for (int i = 0; i < height.size(); i++) {
for (int j = i + 1; j < height.size(); j++) {
int temp = min(height[i], height[j]) * (j - i);
if (temp > max) {
max = temp;
}
}
}*/
//2、双指针法(移动两者中较大者
int i = 0;
int j = height.size() - 1;
int max_value = INT_MIN;
while (i < j) {
int temp = min(height[i], height[j]) * (j - i);
if (height[i] > height[j]) {
j--;
}
else {
i++;
}
if (temp > max_value) {
max_value = temp;
}
}
return max_value;
}
};
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。示例 1:
输入: 3
输出: "III"
示例 2:输入: 4
输出: "IV"
示例 3:输入: 9
输出: "IX"
示例 4:输入: 58
输出: "LVIII"
解释: L = 50, V = 5, III = 3.
示例 5:输入: 1994
输出: "MCMXCIV"
解释: M = 1000, CM = 900, XC = 90, IV = 4.来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/integer-to-roman
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
应该不难
class Solution {
public:
string intToRoman(int num) {
char* c[4][10] = {
{ "","I","II","III","IV","V","VI","VII","VIII","IX" },
{ "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC" },
{ "","C","CC","CCC","CD","D","DC","DCC","DCCC","CM" },
{ "","M","MM","MMM" }
};
string result;
result += c[3][num / 1000];
result += c[2][num / 100 %10];
result += c[1][num / 10 % 10];
result += c[0][num % 10];
return result;
}
};