数据结构牛客网考试两道编程题

环形链表的约瑟夫问题(进阶)

描述:
据说著名犹太历史学家 Josephus 有过以下故事:在罗马人占领乔塔帕特后,39 个犹太人与 Josephus 及他的朋友躲到一个洞中,39 个犹太人决定宁愿死也不要被敌人抓到,于是决定了一种自杀方式,41 个人排成一个圆圈,由第 1 个人开始报数,报数到 3 的人就自杀,然后再由下一个人重新报 1,报数到 3 的人再自杀,这样依次下去,直到剩下最后一个人时,那个人可以自由选择自己的命运。这就是著名的约瑟夫问题。现在请用单向环形链表得出最终存活的人的编号。
输入描述:
一行两个整数 n,m,n 表示链表的长度,m 表示每报数到 m 就自杀。
输出描述:
输出最后存活的人的编号(编号从 1 开始到 n)。
给一个测试用例:
输入:
5 2
复制
输出:
3

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int People_live(int n, int m)
{
    if (n == 1)//如果最后剩一个人
    {
        return 1;//返回最后存活的人
    }
   //链表的长度是:n = n - 1,报到m就自杀:m = m - 1
    //返回新的长度=新的长度%旧得长度加1
    return (People_live(n - 1, m) + m - 1) % n + 1;//递归
}
int main()
{
    int n; int m;
    scanf_s("%d%d", &n, &m);
    printf("%d\n", People_live(n, m));
    return 0;
}

VS验证一下:
在这里插入图片描述

计算二叉树左叶子之和

计算给定二叉树的所有左叶子之和。

示例1:
在这里插入图片描述

在这个二叉树中,有两个左叶子,分别是 8和 18,所以返回 26

示例2:
在这里插入图片描述

在这个二叉树中,没有左叶子,返回0

思路:本题的关键在于如何判断是不是左叶子?平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性,该题可以扩展大家对二叉树的解题思路。

具体方法为:判断父节点的左不为空,且父的左的左为空,且父的左的右为空。因此可以遍历整个二叉树,判断遍历到的每个节点node,判断该node是否满足如下条件,如果满足则将结果值加上该节点做子节点的值,接着再处理左子树和右子树。
此时问题已经转化成对二叉树的遍历了。顺便提一下,遍历可以分为深度优先和广度优先。
深度优先:前中后序遍历,可以使用递归和迭代两种方法,迭代使用栈。
广度优先:层序遍历,使用迭代方法,使用队列。

if(node->left && !node->left->left && !node->left->right)
result += node->left->val;


class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(!root) return 0;
        int result = 0;
        queue<TreeNode*> que;
        que.push(root);
        while(que.size()){
            int size = que.size();
            for(int i = 0; i < size; i++){
                TreeNode* node = que.front();
                que.pop();
                if(node->left && !node->left->left && !node->left->right)
                    result += node->left->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return result;
    }
};                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              		
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值