本文整理了第二天开始刷题的部分笔记记录,作为以后学习参考,有部分解法借鉴了力扣官方和其他题解,但做了完整程序,也就是说可以直接在codeblocks上面运行
罗马数字包含以下七种字符: 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.
题解
思路一:贪心
贪心法则:我们每次尽量使用最大的数来表示。 比如对于 1994 这个数,如果我们每次尽量用最大的数来表示,依次选 1000,900,90,4,会得到正确结果 MCMXCIV。
所以,我们将哈希表按照从大到小的顺序排列,然后遍历哈希表,直到表示完整个输入。
1 / 14
代码
pythonc++
class Solution {
public:
string intToRoman(int num) {
int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
string reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
string res;
int
for (int i = 0; i < 13; i ++ ) //这里不使用图里的count了,一遍一遍来就行了
while(num >= values[i])
{
num -= values[i];
res += reps[i];
}
return res;
}
};
复杂度分析
时间复杂度:O(1)O(1)。最坏条件下,循环的次数为哈希表的长度。
空间复杂度:O(1)O(1)。
思路二:暴力匹配
这个思路相对比较简单,因为题目中说输入在 1 ~3999 的范围内,所以我们把 1 到 9,10 到 90,100 到 900,1000 到 3000 对应的罗马数字都表示出来,最后对于任何输入,我们要做的就是把找到的罗马数字组合起来即可。
比如输入是 2359,我们找到 2000,300,50,9 对应的罗马数字为 MM,CCC,L,IX,组合后得到结果为 MMCCCLIX。
pythonc++
string intToRoman(int num) {
string table[4][10] = { // 1~9
{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},
// 10~90
{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
// 100~900
{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
// 1000~3000
{"", "M", "MM", "MMM"}
};
string result;
int count = 0;
while(num > 0){
int temp = num % 10;
result = table[count][temp] + result;
num /= 10;
count++;
}
return result;
}
复杂度分析
时间复杂度:O(1)O(1)。
空间复杂度:O(1)O(1)。
这个方法相当于牺牲了一部分空间复杂度换取了时间复杂度,因此运行时间更快。
作者:z1m
链接:https://leetcode-cn.com/problems/integer-to-roman/solution/tan-xin-ha-xi-biao-tu-jie-by-ml-zimingmeng/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
难度中等473收藏分享切换为英文关注反馈
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
观察旋转的特点,相对于图案,相当于第i行第j列的元素,变成第j行第n-i列的元素。那么我们就可以通过i和j的对称交换,使第i行第j列的元素和第j行第i列的元素进行交换,然后通过对第j列元素的排序,就可以让第j列变为第n-j列。在这个转化的过程中,原先第j行第i列的元素会先移动到第i行第j列,然后转移到第i行第n-j列,同样符合旋转过程中行列变化的规律。
代码
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int len=matrix.size(),high,low;
for(int i=0;i<len;i++)
for(int j=i;j<len;j++) swap( matrix[i][j],matrix[j][i]);
for(int i=0;i<len;i++)
{
low=0;high=len-1;
while(low<high) swap( matrix[i][low++],matrix[i][high--]);
}
}
};
作者:yan-long-xue-donglin
链接:https://leetcode-cn.com/problems/rotate-image/solution/xuan-zhuan-shuang-bai-by-yan-long-xue-donglin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#include <iostream>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <vector>
using namespace std;
string intToRoman(int num) {
string table[4][10] = { // 1~9
{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},
// 10~90
{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
// 100~900
{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
// 1000~3000
{"", "M", "MM", "MMM"}
};
string result;
int count = 0;
while(num > 0){
int temp = num % 10;
result = table[count][temp] + result;
num /= 10;
cout<<"num = "<<num<<" count = "<<count<<" temp "<< temp<<" table "<<table[count][temp]<<" result "<<result<<endl;
count++;
}
return result;
}
class Solution {
public:
string intToRoman(int num) {
int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
string reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
string res;
for (int i = 0; i < 13; i ++ ) //这里不使用图里的count了,一遍一遍来就行了
while(num >= values[i])
{
num -= values[i];
res += reps[i];
}
return res;
}
};
class Solution2 {
public:
void rotate(vector<vector<int>>& matrix) {
int len=matrix.size(),high,low;
for(int i=0;i<len;i++)
for(int j=i;j<len;j++)
{
swap( matrix[i][j],matrix[j][i]);
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
}
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
for(int i=0;i<len;i++)
{
low=0;high=len-1;
while(low<high) swap( matrix[i][low++],matrix[i][high--]);
}
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
}
};
int main(void)
{
Solution s;
int temp = 0;
Solution2 s2;
#if 0
string result;
cin>>temp;
cout<<endl;
//result = intToRoman(temp);
//result = s.intToRoman(temp);
//cout<<result<<endl;
#endif // 0
//C++输入二维数组
int x = 0;
int col=0;
vector<vector<int>> vec;
vector<int> v;
while(cin >> x){
v.push_back(x);
if(cin.get() == '\n'){
vec.push_back(v);
cout << "col:" << v.size() << endl;
col = v.size();
v.clear();
cout<< "line : = "<<__LINE__<<endl;
}
cout<< "line : = "<<__LINE__<<endl;
if(cin.peek() == '\n'){
vec.push_back(v);
cout<< "line : = "<<__LINE__<<endl;
break;
}
}
cout << "row:" << vec.size() << endl;
cout << "col:" << v.size() << endl;
cout << "验证输出\n";
for(int i = 0; i < vec.size(); i++){
for(int j = 0; j < col; j++){
cout << vec[i][j] << " ";
}
cout<<endl;
}
s2.rotate(vec);
return 0;
}
#if 1
#include <iostream>
#include <string>
#include <unordered_set>
#include <unordered_map>
#include <vector>
using namespace std;
string intToRoman(int num) {
string table[4][10] = { // 1~9
{"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"},
// 10~90
{"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"},
// 100~900
{"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"},
// 1000~3000
{"", "M", "MM", "MMM"}
};
string result;
int count = 0;
while(num > 0){
int temp = num % 10;
result = table[count][temp] + result;
num /= 10;
cout<<"num = "<<num<<" count = "<<count<<" temp "<< temp<<" table "<<table[count][temp]<<" result "<<result<<endl;
count++;
}
return result;
}
class Solution {
public:
string intToRoman(int num) {
int values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
string reps[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
string res;
for (int i = 0; i < 13; i ++ ) //这里不使用图里的count了,一遍一遍来就行了
while(num >= values[i])
{
num -= values[i];
res += reps[i];
}
return res;
}
};
class Solution2 {
public:
void rotate(vector<vector<int>>& matrix) {
int len=matrix.size(),high,low;
for(int i=0;i<len;i++)
for(int j=i;j<len;j++)
{
swap( matrix[i][j],matrix[j][i]);
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
}
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
for(int i=0;i<len;i++)
{
low=0;high=len-1;
while(low<high) swap( matrix[i][low++],matrix[i][high--]);
}
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < len; j++){
cout << matrix[i][j] << " ";
}
cout<<endl;
}
}
};
int main(void)
{
Solution s;
int temp = 0;
Solution2 s2;
#if 0
string result;
cin>>temp;
cout<<endl;
//result = intToRoman(temp);
//result = s.intToRoman(temp);
//cout<<result<<endl;
#endif // 0
#if 1
//C++输入二维数组
int x = 0;
int col=0;
// vector<vector<int>> vec;
int N=2, M=2;
vector<vector<int> > vec(N, vector<int>(M)); //定义二维动态数组5行6列
vector<int> v;
while(cin >> x){
v.push_back(x);
if(cin.get() == '\n'){
vec.push_back(v);
cout << "col:" << v.size() << endl;
col = v.size();
v.clear();
cout<< "line : = "<<__LINE__<<endl;
}
cout<< "line : = "<<__LINE__<<endl;
if(cin.peek() == '\n'){
vec.push_back(v);
cout<< "line : = "<<__LINE__<<endl;
break;
}
}
cout << "row:" << vec.size() << endl;
cout << "col:" << v.size() << endl;
cout << "验证输出\n";
for(int i = 0; i < vec.size(); i++){
for(int j = 0; j < col; j++){
cout << vec[i][j] << " ";
}
cout<<endl;
}
s2.rotate(vec);
#endif // 0
//创建2*3的vector容器v,初始值均初始化为0 1 2 1 2 3
//vector<vector<int> > v(2, vector<int>(1, 0));
#if 0
int N=2, M=2;
vector<vector<int> > v(N, vector<int>(M)); //定义二维动态数组5行6列
//vector<vector<int>> v(N);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
v[i][j] = i + j;
}
s2.rotate(v);
#endif // 0
return 0;
}
#endif // 0
#if 0
/*https://blog.csdn.net/abc_xian/article/details/100164594*/
#include <iostream>
#include <vector>
using namespace std;
void function1(vector<vector<int> > vec)
{
cout << "-----------------------------------------" << endl;
//打印vec的地址
cout << "function1.&vec:" << &vec << endl;
//打印vec[i]的地址(即第一层vector的地址)
cout << "function1.&vec[i]:" << endl;
for (int i = 0; i < 2; i++)
cout << &vec[i] << endl;
//打印vec的各元素地址
cout << "function1.&vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << &vec[i][j] << " ";
cout << endl;
}
cout << "---------------------------" << endl;
//打印vec的各元素值
cout << "function1.vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << vec[i][j] << " ";
cout << endl;
}
}
void function2(vector<vector<int> > &vec)
{
cout << "-----------------------------------------" << endl;
//打印vec的地址
cout << "function2.&vec:" << &vec << endl;
//打印vec[i]的地址(即第一层vector的地址)
cout << "function2.&vec[i]:" << endl;
for (int i = 0; i < 2; i++)
cout << &vec[i] << endl;
//打印vec的各元素地址
cout << "function2.&vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << &vec[i][j] << " ";
cout << endl;
}
cout << "---------------------------" << endl;
//打印vec的各元素值
cout << "function2.vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << vec[i][j] << " ";
cout << endl;
}
}
void function3(vector<vector<int> > *vec)
{
cout << "-----------------------------------------" << endl;
//打印vec的地址
cout << "function3.&vec:" << vec << endl;
//打印vec[i]的地址(即第一层vector的地址)
cout << "function3.&vec[i]:" << endl;
for (int i = 0; i < 2; i++)
cout << &(*vec)[i] << endl;
//打印vec的各元素地址
cout << "function3.&vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << &(*vec)[i][j] << " ";
cout << endl;
}
cout << "---------------------------" << endl;
//打印vec的各元素值
cout << "function3.vec[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << (*vec)[i][j] << " ";
cout << endl;
}
}
int main()
{
//创建2*3的vector容器v,初始值均初始化为0 1 2 1 2 3
vector<vector<int> > v(2, vector<int>(3, 0));
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
v[i][j] = i + j;
}
//打印v的地址
cout << "&v:" << &v << endl;
//打印v[i]的地址(即第一层vector的地址)
cout << "&v[i]:" << endl;
for (int i = 0; i < 2; i++)
cout << &v[i] << endl;
//打印v的各元素地址
cout << "&v[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << &v[i][j] << " ";
cout << endl;
}
cout << "---------------------------" << endl;
//打印v的各元素值
cout << "v[i][j]:" << endl;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << v[i][j] << " ";
cout << endl;
}
function1(v);
function2(v);
function3(&v);
return 0;
}
#endif
难度中等284收藏分享切换为英文关注反馈
给定一个二叉树,返回它的 前序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
来自 <https://leetcode-cn.com/problems/binary-tree-preorder-traversal/>
C++简洁代码(递归/迭代双百):
Orange发布于 2 天前64C++
解题思路
方法一:递归
1.思路:根左右的遍历方式
方法二:迭代双百
1.将节点压入栈内,边压边存入vector容器
2.当无根节点时,栈弹出,并转右节点(根节点其实就是左节点)
代码
- 递归
- 迭代
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
if(root) {
res.push_back(root->val); //根
preorderTraversal(root->left); //左
preorderTraversal(root->right); //右
}
return res;
}
};
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
TreeNode* cur = root;
while(cur || stk.size()) {
while(cur) {
stk.push(cur);
res.push_back(cur->val);
cur = cur->left;
}
cur = stk.top();
stk.pop();
cur = cur->right;
}
return res;
}
};
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
vector<int> res;
vector<int> preorderTraversal(TreeNode* root) {
if(root) {
res.push_back(root->val); //根
preorderTraversal(root->left); //左
preorderTraversal(root->right); //右
}
return res;
}
};
/*
程序说明:
preOrderRecur 递归方式实现先序遍历
inOrderRecur 递归方式实现中序遍历
posOrderRecur 递归方式实现后序遍历
preOrderUnRecur 非递归方式实现先序遍历
inOrderUnRecur 非递归方式实现中序遍历
posOrderUnRecur 非递归方式实现后序遍历
————————————————
版权声明:本文为CSDN博主「alxe_made」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/alxe_made/article/details/94721195
*/
struct Node {
int value;
Node* left;
Node* right;
Node(int value):
value(value), left(nullptr), right(nullptr) {}
};
void preOrderRecur(Node* head) {
if (head == nullptr) {
return;
}
std::cout << head->value << ","<<endl;
cout<<head->left<< " head right "<< head->right <<endl;
preOrderRecur(head->left);
preOrderRecur(head->right);
}
void inOrderRecur(Node* head) {
if (head == nullptr) {
return;
}
inOrderRecur(head->left);
std::cout << head->value << ",";
inOrderRecur(head->right);
}
void posOrderRecur(Node* head) {
if (head == nullptr) {
return;
}
posOrderRecur(head->left);
posOrderRecur(head->right);
std::cout << head->value << ",";
}
void preOrderUnRecur(Node* head) {
if (head == nullptr) {
return;
}
std::stack<Node*> nstack;
nstack.push(head);
while(!nstack.empty()) {
Node* head = nstack.top(); // get stack top
std::cout << head->value << ",";
nstack.pop();
if (head->right != nullptr) {
nstack.push(head->right);
}
if (head->left != nullptr) {
nstack.push(head->left);
}
}
}
void inOrderUnRecur(Node* head) {
if (head == nullptr) {
return;
}
std::stack<Node*> nstack;
while (!nstack.empty() || head != nullptr) {
if (head != nullptr) {
nstack.push(head);
head = head->left;
} else {
head = nstack.top();
std::cout << head->value << ",";
nstack.pop();
head = head->right;
}
}
}
void posOrderUnRecur(Node* head) {
if (head == nullptr) {
return;
}
std::stack<Node*> nstack1, nstack2;
nstack1.push(head);
while (!nstack1.empty()) {
Node* head = nstack1.top();
nstack2.push(head);
nstack1.pop();
if (head->left != nullptr) {
nstack1.push(head->left);
}
if (head->right != nullptr) {
nstack1.push(head->right);
}
}
while (!nstack2.empty()) {
std::cout << nstack2.top()->value << ",";
nstack2.pop();
}
}
int main() {
Solution so;
vector<int> res1;
Node* head = new Node(5);
head->left = new Node(3);
head->right = new Node(8);
head->left->left = new Node(2);
head->left->right = new Node(4);
head->right->left = new Node(7);
head->right->right = new Node(10);
head->right->left->left = new Node(6);
head->right->right->left = new Node(9);
head->right->right->right = new Node(11);
/*
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,2,3]
*/
TreeNode* treeheadnode = new TreeNode(1);
treeheadnode->right = new TreeNode(2);
treeheadnode->right->left = new TreeNode(3);
res1= so.preorderTraversal(treeheadnode);
/*三种方式对应的调用形式分别为:
function1(vec),传入值
function2(vec),传入引用
function3(&vec),传入地址
三种方式的效果分别为:
会发生拷贝构造
不会发生拷贝构造
不会发生拷贝构造
*/
for(int i =0;i< res1.size();i++)
{
cout<< res1[i]<<endl;
}
std::cout << "==============recursive==============";
std::cout << "\npre-order: ";
preOrderRecur(head);
#if 0
std::cout << "\nin-order: ";
inOrderRecur(head);
std::cout << "\npos-order: ";
posOrderRecur(head);
std::cout << "\n==============un-recursive==============";
std::cout << "\npre-order: ";
preOrderUnRecur(head);
std::cout << "\nin-order: ";
inOrderUnRecur(head);
std::cout << "\npos-order: ";
posOrderUnRecur(head);
#endif // 0
return 0;
}
难度中等539收藏分享切换为英文关注反馈
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [1,3,2]
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode* root) {
if(root != NULL)
{
inorderTraversal(root->left);
res.push_back(root->val);
inorderTraversal(root->right);
}
return res;
}
};
难度困难332收藏分享切换为英文关注反馈
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
类的构造函数
类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。
构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。
假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示:
C::C( double a, double b, double c): X(a), Y(b), Z(c) { .... }
* };
*/
class Solution {
public:
vector<int> res;
vector<int> postorderTraversal(TreeNode* root) {
if(root != NULL)
{
postorderTraversal(root->left);
postorderTraversal(root->right);
res.push_back(root->val);
}
return res;
}
};