leedcode刷题记录 | 代码详解

1. 最长回文子串<5>

题目:

给你一个字符串 s,找到 s 中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”

动态规划的特性:

  1. 后续的计算可以使用之前的计算结果
  2. 空间换时间

本题回文串本身就具有动态规划的特性

代码:

string longestPalindrome(string s) {
        int n = s.size();
	// 单个字符直接返回   (特殊情况)
	if (n < 2) return s;
	// 回文子串的最大长度
	int maxLen = 1;
	// 回文子串的起始位置
	int begin = 0;
	// dp[i][j] 表示s[i...j]是否是回文串
	// n行n列个0
	vector<vector<int>> dp(n,vector<int>(n));
	for (int i = 0; i < n; i++) {
		dp[i][i] = true; // 对角线设置为True,这样表示单个字符一定是回文串
	}

	// 递推开始
	// 从列开始
	for (int j = 1; j < n; j++) {
		//填该列的数据
		for (int i = 0; i < j; i++) {
			// 如果两端字符不相等
			if (s[i] != s[j]) dp[i][j] = false;
			else{
				// (j-1)-(i+1)+1< 2  即去除两端字符后,子串长度为0或1时,表示是回文串
				if (j - i < 3) {
					dp[i][j] = true;
				}else{
					// 参考之前的计算结果
					dp[i][j] = dp[i + 1][j - 1];
				}
			}

			// j - i + 1为子串长度  dp[i][j]表示是否为回文串
			if (dp[i][j] && j - i + 1 > maxLen) {
				maxLen = j - i + 1;
				begin = i;
			}
		}		
	}
	return s.substr(begin, maxLen);
    }

2. N 字形变换<6>

题目:

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P A H N
A P L S I I G
Y I R
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:
输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”
示例 2:
输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I
示例 3:
输入:s = “A”, numRows = 1
输出:“A”

代码:

class Solution {
public:
    string convert(string s, int numRows) {
	int n = s.length(), r = numRows;
	// r=1只有一行 r>=n 只有一列
	if ( r == 1 || r >= n) return s;
	// 先向下填写r个字符,之后r-2列,每列填写1个字符  即r+r-2 = 2r-2  为周期  => 2r-2个字符为一个周期
	int t = r * 2 - 2;
	// 字符串共n个字符,共n/t个周期,每个周期r-1列
	// 为保证向上取整 n+t
	int c = (n + t) / t * (r - 1);
	vector<string> mat(r, string(c, 0));
	// i是字符指针,x y是二维数组坐标
	for (int i = 0, x = 0, y = 0; i < n; i++) {
		mat[x][y] = s[i];
		// 这里是先填字符,然后移动坐标
		if (i % t < r-1) {
			x++; // 向下移动
		}
		else {
			x--;
			y++; // 向右上移动
		}
	}
	string ans;
	for (auto& row : mat) {
		for (char ch : row) {
			if (ch) {
				ans += ch;
			}
		}
	}
	return ans;
}

};

3.整数翻转<7>

题目:

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0

弹出 x 的末尾数字 digit
digit = x % 10
x /= 10

将数字 digit 推入 rev 末尾
rev = rev * 10 + digit

pass:其实判断条件可以简化的,因为x本身会被int限制,当x为正数并且位数和Integer.MAX_VALUE的位数相等时首位最大只能为2,所以逆转后不会出现res = Integer.MAX_VALUE / 10 && tmp > 2的情况,自然也不需要判断res==214748364 && tmp>7了,反之负数情况也一样

代码:

class Solution {
public:
int reverse(int x){
	int res = 0;
	while ( x != 0 )
	{
		int num = x % 10; // 个位数
		x /= 10; // 除去个位数之后的数

		// INT_MAX表示最大整数,INT_MIN表示最小整数
		// 如果溢出
		if (res > INT_MAX / 10 || res < INT_MIN / 10){
			return 0;
		}

		// x将末尾数字 推入 res中
		res = res * 10 + num;
	}

	return res;
}
};

4. 字符串转换整数 <8>

题目

https://leetcode.cn/problems/string-to-integer-atoi/

代码:

int myAtoi(string str) {
	int res = 0;
	int i = 0;
	//默认符号为1
	int flag = 1;
	// 如果是空格,那么后移指针i
	while (str[i] == ' ') { i++; }
	// 如果遇到-,flag置为-1
	if (str[i] == '-') { flag = -1; }
	// 遇到符号依然后移指针
	if (str[i] == '+' || str[i] == '-') { i++; }

	// 这里是从高位的位置开始扫描
	while (i < str.size() && isdigit(str[i])) {
		
		// 数字型的字符串可以相减
		// 若是不减去'0',直接转int 会变成ASCII
		int r = str[i] - '0';

		if (res > INT_MAX / 10 || (res == INT_MAX / 10 && r > 7)) {
			return flag > 0 ? INT_MAX : INT_MIN;
		}
		// 字符翻转时,是从低位扫描,然后推入新数字中
		// 这里要保持原数字顺序不表
		res = res * 10 + r;
		i++;
		
	}
	return flag > 0 ? res : -res;
}

5. 回文数<9>

题目:

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。

用的方法是,转为字符串,然后翻转,再比较
代码:

bool isPalindrome(int x) {
	// 转化为字符串
	string s = to_string(x);
	// 新建一个副本
	string str_e = s;
	// 翻转
	reverse(str_e.begin(), str_e.end());
	// 比较
	return s == str_e;
}

python用习惯了,第一反应就是字符串翻转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旭旭老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值