
目录
1. 旋转链表 ★★
2. 跳跃游戏 ★
3. 求根节点到叶节点数字之和 ★★★
1. 旋转链表
给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
示例 1:

输入:head = [1,2,3,4,5], k = 2 输出:[4,5,1,2,3]
示例 2:

输入:head = [0,1,2], k = 4 输出:[2,0,1]
提示:
- 链表中节点的数目在范围
[0, 500]内 -100 <= Node.val <= 1000 <= k <= 2 * 10^9
#include <bits/stdc++.h>
using namespace std;
struct ListNode
{
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution
{
public:
ListNode *rotateRight(ListNode *head, int k)
{
if (head == nullptr)
{
return head;
}
int len = 0;
ListNode dummy;
dummy.next = head;
ListNode *tail = &dummy;
while (tail->next != nullptr)
{
len++;
tail = tail->next;
}
ListNode *prev = &dummy;
ListNode *p = head;
k = k % len;
for (int i = 0; i < len - k; i++)
{
prev = p;
p = p->next;
}
if (p != nullptr)
{
prev->next = tail->next;
tail->next = head;
head = p;
}
return head;
}
};
ListNode* createLinkedList(vector<int>& vec) {
if (vec.empty()) {
return NULL;
}
ListNode* head = new ListNode(vec[0]);
ListNode* curNode = head;
for (int i = 1; i < vec.size(); i++) {
curNode->next = new ListNode(vec[i]);
curNode = curNode->next;
}
return head;
}
void printLinkedList(ListNode* head) {
ListNode* curNode = head;
while (curNode != NULL) {
cout << curNode->val << " -> ";
curNode = curNode->next;
}
cout << "NULL" << endl;
}
string LList2String(ListNode* head) {
ListNode* curNode = head;
int size = 0;
string res = "[";
while (curNode != NULL) {
res += size++ > 0 ? "," : "";
res += to_string(curNode->val);
curNode = curNode->next;
}
return res + "]";
}
int main()
{
Solution s;
vector<int> nums = {1,2,3,4,5};
ListNode* head = createLinkedList(nums);
printLinkedList(head);
head = s.rotateRight(head, 2);
printLinkedList(head);
cout << LList2String(head) << endl;
nums = {0,1,2};
head = createLinkedList(nums);
printLinkedList(head);
head = s.rotateRight(head, 4);
printLinkedList(head);
cout << LList2String(head) << endl;
return 0;
}
输出:
1 -> 2 -> 3 -> 4 -> 5 -> NULL
4 -> 5 -> 1 -> 2 -> 3 -> NULL
[4,5,1,2,3]
0 -> 1 -> 2 -> NULL
2 -> 0 -> 1 -> NULL
[2,0,1]
2. 跳跃游戏
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4] 输出:true 解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4] 输出:false 解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
提示:
1 <= nums.length <= 3 * 10^40 <= nums[i] <= 10^5
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
static inline int max(int a, int b)
{
return a > b ? a : b;
}
static bool canJump(int *nums, int numsSize)
{
int i, pos = 0;
for (i = 0; i < numsSize - 1; i++)
{
if (pos < i || pos >= numsSize - 1)
{
continue;
}
pos = max(i + nums[i], pos);
}
return pos >= numsSize - 1;
}
int main()
{
int nums1[5] = {2,3,1,1,4};
printf("%s\n", canJump(nums1, 5) ? "true" : "false");
int nums2[5] = {3,2,1,0,4};
printf("%s\n", canJump(nums2, 5) ? "true" : "false");
return 0;
}
输出:
true
false
3. 求根节点到叶节点数字之和
给你一个二叉树的根节点 root ,树中每个节点都存放有一个 0 到 9 之间的数字。
每条从根节点到叶节点的路径都代表一个数字:
例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123 。
计算从根节点到叶节点生成的 所有数字之和 。
叶节点 是指没有子节点的节点。
示例 1:

输入:root = [1,2,3] 输出:25 解释: 从根到叶子节点路径 1->2 代表数字 12 从根到叶子节点路径 1->3 代表数字 13 因此,数字总和 = 12 + 13 = 25
示例 2:

输入:root = [4,9,0,5,1] 输出:1026 解释: 从根到叶子节点路径 4->9->5 代表数字 495 从根到叶子节点路径 4->9->1 代表数字 491 从根到叶子节点路径 4->0 代表数字 40 因此,数字总和 = 495 + 491 + 40 = 1026
提示:
- 树中节点的数目在范围
[1, 1000]内 0 <= Node.val <= 9- 树的深度不超过
10
代码:
#include <bits/stdc++.h>
#define null INT_MIN
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution
{
public:
int sumNumbers(TreeNode *root)
{
if (root == nullptr)
return 0;
int result = 0;
vector<int> num;
vector<int> temp;
recursive(root, &num, &temp);
for (int i = 0; i < num.size(); i++)
{
result = result + num[i];
}
return result;
}
void recursive(TreeNode *root, vector<int> *num, vector<int> *temp)
{
temp->push_back(root->val);
if (root->left == nullptr && root->right == nullptr)
{
int sum = 0;
for (int i = temp->size() - 1; i >= 0; i--)
{
int howi = (*temp)[i];
sum = sum + howi * pow(10, (temp->size() - i - 1));
}
num->push_back(sum);
temp->pop_back();
return;
}
if (root->left) recursive(root->left, num, temp);
if (root->right) recursive(root->right, num, temp);
temp->pop_back();
}
};
TreeNode* buildTree(vector<int>& nums)
{
if (nums.empty()) return nullptr;
TreeNode *root = new TreeNode(nums.front());
queue<TreeNode*> q;
q.push(root);
int i = 1;
while(!q.empty() && i < nums.size())
{
TreeNode *cur = q.front();
q.pop();
if(i < nums.size() && nums[i] != null)
{
cur->left = new TreeNode(nums[i]);
q.push(cur->left);
}
i++;
if(i < nums.size() && nums[i] != null)
{
cur->right = new TreeNode(nums[i]);
q.push(cur->right);
}
i++;
}
return root;
}
int main()
{
Solution s;
vector<int> nums = {1,2,3};
TreeNode* root = buildTree(nums);
cout << s.sumNumbers(root) << endl;
nums = {4,9,0,5,1};
root = buildTree(nums);
cout << s.sumNumbers(root) << endl;
return 0;
}
输出:
25
1026
非递归法: stack / DFS
从根节点开始遍历二叉树,记录当前路径上的数字,如果遇到叶子节点,则将该数字加入结果中。最后返回所有叶子节点对应的数字之和即可。
#include <bits/stdc++.h>
#define null INT_MIN
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
class Solution
{
public:
int sumNumbers(TreeNode *root)
{
if (root == nullptr)
return 0;
int result = 0;
vector<int> num;
stack<pair<TreeNode *, vector<int>>> st;
st.push(make_pair(root, vector<int>{}));
while (!st.empty())
{
auto node = st.top().first;
auto temp = st.top().second;
st.pop();
temp.push_back(node->val);
if (node->left == nullptr && node->right == nullptr)
{
int sum = 0;
for (int i = temp.size() - 1; i >= 0; i--)
{
int howi = temp[i];
sum = sum + howi * pow(10, (temp.size() - i - 1));
}
num.push_back(sum);
}
if (node->left) st.push(make_pair(node->left, temp));
if (node->right) st.push(make_pair(node->right, temp));
}
for (int i = 0; i < num.size(); i++)
{
result = result + num[i];
}
return result;
}
};
TreeNode* buildTree(vector<int>& nums)
{
if (nums.empty()) return nullptr;
TreeNode *root = new TreeNode(nums.front());
queue<TreeNode*> q;
q.push(root);
int i = 1;
while(!q.empty() && i < nums.size())
{
TreeNode *cur = q.front();
q.pop();
if(i < nums.size() && nums[i] != null)
{
cur->left = new TreeNode(nums[i]);
q.push(cur->left);
}
i++;
if(i < nums.size() && nums[i] != null)
{
cur->right = new TreeNode(nums[i]);
q.push(cur->right);
}
i++;
}
return root;
}
int main()
{
Solution s;
vector<int> nums = {1,2,3};
TreeNode* root = buildTree(nums);
cout << s.sumNumbers(root) << endl;
nums = {4,9,0,5,1};
root = buildTree(nums);
cout << s.sumNumbers(root) << endl;
nums = {4,9,0,null,null,5,1};
root = buildTree(nums);
cout << s.sumNumbers(root) << endl;
return 0;
}
输出:
25
1026
855
🌟 每日一练刷题专栏
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
| C/C++ 每日一练 专栏 |
| Python 每日一练 专栏 |

文章提供了三个编程问题的解决方案:1)旋转链表,通过C++实现右移节点;2)跳跃游戏,判断能否到达数组最后一个下标,用C实现;3)求二叉树根到叶节点数字之和,分别用递归和非递归的C++方法解决。每个问题都有详细的代码示例和测试用例。
6510

被折叠的 条评论
为什么被折叠?



