本文整理了第二天开始刷题的部分笔记记录,作为以后学习参考,有部分解法借鉴了力扣官方和其他题解,但做了完整程序,也就是说可以直接在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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
48. 旋转图像
难度中等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
int len=matrix.size(),high,low;
for(int i=0;i for(int j=i;j for(int i=0;i { low=0;high=len-1; while(low } } }; 作者:yan-long-xue-donglin 链接:https://leetcode-cn.com/problems/rotate-image/solution/xuan-zhuan-shuang-bai-by-yan-long-xue-donglin/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 #include #include #include #include #include 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 = "< 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 int len=matrix.size(),high,low; for(int i=0;i for(int j=i;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< } } for(int i = 0; i < matrix.size(); i++){ for(int j = 0; j < len; j++){ cout << matrix[i][j] << " "; } cout< } for(int i=0;i { low=0;high=len-1; while(low } for(int i = 0; i < matrix.size(); i++){ for(int j = 0; j < len; j++){ cout << matrix[i][j] << " "; } cout< } } }; int main(void) { Solution s; int temp = 0; Solution2 s2; #if 0 string result; cin>>temp; cout< //result = intToRoman(temp); //result = s.intToRoman(temp); //cout< #endif // 0 //C++输入二维数组 int x = 0; int col=0; vector vector 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__< } cout<< "line : = "<<__LINE__< if(cin.peek() == '\n'){ vec.push_back(v); cout<< "line : = "<<__LINE__< 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< } s2.rotate(vec); return 0; } #if 1 #include #include #include #include #include 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 = "< 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 int len=matrix.size(),high,low; for(int i=0;i for(int j=i;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< } } for(int i = 0; i < matrix.size(); i++){ for(int j = 0; j < len; j++){ cout << matrix[i][j] << " "; } cout< } for(int i=0;i { low=0;high=len-1; while(low } for(int i = 0; i < matrix.size(); i++){ for(int j = 0; j < len; j++){ cout << matrix[i][j] << " "; } cout< } } }; int main(void) { Solution s; int temp = 0; Solution2 s2; #if 0 string result; cin>>temp; cout< //result = intToRoman(temp); //result = s.intToRoman(temp); //cout< #endif // 0 #if 1 //C++输入二维数组 int x = 0; int col=0; // vector int N=2, M=2; vector vector 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__< } cout<< "line : = "<<__LINE__< if(cin.peek() == '\n'){ vec.push_back(v); cout<< "line : = "<<__LINE__< 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< } s2.rotate(vec); #endif // 0 //创建2*3的vector容器v,初始值均初始化为0 1 2 1 2 3 //vector #if 0 int N=2, M=2; vector //vector 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 #include using namespace std; void function1(vector { 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 { 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 { 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 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 144. 二叉树的前序遍历 难度中等284收藏分享切换为英文关注反馈 给定一个二叉树,返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 来自 C++简洁代码(递归/迭代双百): Orange发布于 2 天前64C++ 解题思路 方法一:递归 1.思路:根左右的遍历方式 方法二:迭代双百 1.将节点压入栈内,边压边存入vector容器 2.当无根节点时,栈弹出,并转右节点(根节点其实就是左节点) 代码 class Solution { class Solution { public: vector vector stack 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 #include #include using namespace std; struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; class Solution { public: vector vector 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 << ","< cout< 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 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 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 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 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]< } 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; } 94. 二叉树的中序遍历 难度中等539收藏分享切换为英文关注反馈 给定一个二叉树,返回它的中序 遍历。 示例: 输入: [1,null,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; } }; 145. 二叉树的后序遍历 难度困难332收藏分享切换为英文关注反馈 给定一个二叉树,返回它的 后序 遍历。 示例: 输入: [1,null,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; } };
1
\
2
/
3
public:
vector
vector
if(root) {
res.push_back(root->val); //根
preorderTraversal(root->left); //左
preorderTraversal(root->right); //右
}
return res;
}
};
1
\
2
/
3
1
\
2
/
3