C/C++每日一练(20230313) 旋转链表、跳跃游戏、根节点到叶节点数字之和

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

目录

1. 旋转链表  ★★

2. 跳跃游戏  ★

3. 求根节点到叶节点数字之和  ★★★

🌟 每日一练刷题专栏

C/C++ 每日一练 ​专栏

Python 每日一练 专栏


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 <= 100
  • 0 <= 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^4
  • 0 <= 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 每日一练 专栏

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hann Yang

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

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

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

打赏作者

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

抵扣说明:

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

余额充值