【算法】009、单双链表反转
【算法】009、单双链表反转
文章目录
- 一、单链表反转
- 1.1 实现思路
- 1.2 多语言解法
- 二、双链表反转
- 2.1 实现思路
- 2.2 多语言解法
一、单链表反转
1.1 实现思路
维护 pre 变量。
从前向后遍历 head,首先记录 next = head.next,其次反转指针使 head.next = pre. 再向后迭代使 pre = head,head = next。
直到遍历完 head == nil 为止。最终 pre 就是原链表的尾节点(即新链表的头节点),返回 pre 即可。
// go
package mainimport "fmt"// single
type Node struct {val intnext *Node
}func main() {la := la()laCheck(reverse(la))lb := lb()if reverse(lb) != lb {panic("error for lb")}lnil := lnil()if reverse(lnil) != nil {panic("error for nil")}print("ok")
}func la() *Node {a := &Node{val: 0}b := &Node{val: 1}c := &Node{val: 2}a.next = bb.next = creturn a
}func laCheck(h *Node) error {ans := make([]int, 0)for iter := h; iter != nil; iter = iter.next {ans = append(ans, iter.val)}if len(ans) != 3 {return fmt.Errorf("err len")}if ans[0] != 3 {return fmt.Errorf("err val")}if ans[1] != 1 {return fmt.Errorf("err val")}if ans[2] != 0 {return fmt.Errorf("err val")}return nil
}func lb() *Node {return &Node{val: 5, next: nil}
}func lnil() *Node {var n *Node = nilreturn n
}func reverse(head *Node) *Node {if head == nil {return nil}var pre *Node = nilvar next *Node = nilfor head != nil {next = head.next // 备份 head.next, 因为下一行就要改其指向了head.next = pre // 反转的关键, 指针方向变了, 原来 head.next 指向 next, 现在 head.next 指向 prepre = head // 向后迭代head = next // 同上}return pre
}
1.2 多语言解法
C p p / G o / P y t h o n / R u s t / J s / T s Cpp/Go/Python/Rust/Js/Ts Cpp/Go/Python/Rust/Js/Ts
// cpp
#include <iostream>
#include <vector>
#include <algorithm>using namespace std;
struct Node
{int val;Node *next;
};Node *la()
{Node *c = new Node{2, nullptr};Node *b = new Node{1, c};Node *a = new Node{0, b};return a;
}void laCheck(Node *head)
{vector<int> ans;Node *iter = head;while (iter != nullptr){ans.push_back(iter->val);iter = iter->next;}if (ans.size() != 3){throw runtime_error("length error");}if (ans[0] != 2){throw runtime_error("0 error");}if (ans[1] != 1){throw runtime_error("1 error");}if (ans[2] != 0){throw runtime_error("2 error");}
}Node *lb()
{return new Node{5, nullptr};
}void lbCheck(Node *head)
{vector<int> ans;Node *iter = head;while (iter){ans.push_back(iter->val);iter = iter->next;}if (ans.size() != 1){throw runtime_error("length error");}if (ans[0] != 5){throw runtime_error("5 error");}
}Node *lnone()
{return nullptr;
}Node *reverse(Node *head)
{Node *pre = nullptr;Node *iter = head;while (iter){Node *next = iter->next;iter->next = pre;pre = iter;iter = next;}return pre;
}int main()
{Node *l = la();Node *r = reverse(l);laCheck(r);l = lb();r = reverse(l);lbCheck(r);l = lnone();r = reverse(l);if (r != nullptr){throw runtime_error("error for lnone");}cout << "ok" << endl;
}
// go 同上
# python
class Node(object):def __init__(self, v, n):self.val = vself.next = ndef la():c = Node(2, None)b = Node(1, c)a = Node(0, b)return adef laCheck(n):ans = []while n:ans.append(n.val)n = n.nextif ans != [2, 1, 0]:raise ValueErrordef lb():return Node(5, None)def reverse(head):pre = Nonenext = Nonewhile head:next = head.nexthead.next = prepre = headhead = nextreturn predef main():l = la()l = reverse(l)laCheck(l)l = lb()if reverse(l) != l:raise ValueError(123)if reverse(None) != None:raise ValueError(111)print("ok")if __name__ == "__main__":main()
// rust
fn main() {let l = la();let r = reverse(l);la_check(r).expect("la_check");let l = lb();let r = reverse(l);lb_check(r).expect("lb_check");let l = lnone();let r = reverse(l);if r.is_some() {panic!("lnone");}println!("ok")
}#[derive(Debug)]
struct Node {val: i32,next: Option<Box<Node>>,
}impl Node {fn new(val: i32, next: Option<Box<Node>>) -> Self {Self { val, next }}
}fn la() -> Option<Box<Node>> {let c = Some(Box::new(Node::new(2, None)));let b = Some(Box::new(Node::new(1, c)));let a = Some(Box::new(Node::new(0, b)));a
}fn la_check(head: Option<Box<Node>>) -> Result<(), String> {let mut ans = vec![];let mut iter = head;while let Some(node) = iter {ans.push(node.val);iter = node.next;}if ans.len() != 3 {return Err("len".to_string());}if ans[0] != 2 {return Err("0".to_string());}if ans[1] != 1 {return Err("1".to_string());}if ans[2] != 0 {return Err("2".to_string());}Ok(())
}fn lb() -> Option<Box<Node>> {Some(Box::new(Node::new(5, None)))
}fn lb_check(head: Option<Box<Node>>) -> Result<(), String> {let mut ans = vec![];let mut head = head;while let Some(node) = head {ans.push(node.val);head = node.next;}if ans.len() != 1 {return Err("len".to_string());}if ans[0] != 5 {return Err("5".to_string());}Ok(())
}fn lnone() -> Option<Box<Node>> {None
}fn reverse(head: Option<Box<Node>>) -> Option<Box<Node>> {let mut head = head;let mut pre: Option<Box<Node>> = None;while let Some(mut node) = head {let next = node.next.take();node.next = pre;pre = Some(node);head = next;}pre
}
// js
// ts
function main() {let l = la();let r = reverse(l);laCheck(r);l = lb();r = reverse(l);lbCheck(r);l = lnone();r = reverse(l);if (r) {throw new Error("lnone");}console.log("ok");
}class ListNode {val: number;next: ListNode | null;constructor(val: number, next: ListNode | null) {this.val = val;this.next = next;}
}function la(): ListNode | null {const c = new ListNode(2, null);const b = new ListNode(1, c);const a = new ListNode(0, b);return a;
}function laCheck(head: ListNode | null) {const ans: number[] = [];let iter: ListNode | null = head;while (iter) {ans.push(iter.val);iter = iter.next;}if (ans.length !== 3) {throw new Error("length");}if (ans[0] !== 2) {throw new Error("0")}if (ans[1] !== 1) {throw new Error("1");}if (ans[2] !== 0) {throw new Error("2");}
}function lb(): ListNode {return new ListNode(5, null);
}function lbCheck(head: ListNode | null) {const ans: number[] = [];let iter: ListNode | null = head;while (iter) {ans.push(iter.val);iter = iter.next;}if (ans.length !== 1) {throw new Error("length");}if (ans[0] !== 5) {throw new Error("5");}
}function lnone(): ListNode | null {return null;
}function reverse(head: ListNode | null): ListNode | null {let pre: ListNode | null = null;while (head) {const next = head.next;head.next = pre;pre = head;head = next;}return pre;
}main();
二、双链表反转
2.1 实现思路
和 单链表反转 相同,每次反转两个指针即可,即 head.next = pre 和 head.pre = next。
package mainfunc main() {l := la()r := reverse(l)laCheck(r)l = lb()r = reverse(l)lbCheck(r)r = reverse(nil)if r != nil {panic("lnil")}println("ok")
}type Node struct {val intpre *Nodenext *Node
}func la() *Node {c := &Node{2, nil, nil}b := &Node{1, nil, c}a := &Node{0, nil, b}c.pre = bb.pre = areturn a
}func laCheck(h *Node) {ans := []int{}iter := hfor iter != nil {ans = append(ans, iter.val)iter = iter.next}if len(ans) != 3 {panic("length is not 3")}if ans[0] != 2 {panic("0 is not the first element")}if ans[1] != 1 {panic("1 is not the second element")}if ans[2] != 0 {panic("2 is not the third element")}
}
func lbCheck(h *Node) {ans := []int{}iter := hfor iter != nil {ans = append(ans, iter.val)iter = iter.next}if len(ans) != 1 {panic("length is not 3")}if ans[0] != 5 {panic("0 is not the first element")}
}func lb() *Node {return &Node{5, nil, nil}
}func reverse(h *Node) *Node {var pre *Node = niliter := hfor iter != nil {next := iter.nextiter.next = preiter.pre = nextpre = iteriter = next}return pre
}
2.2 多语言解法
C p p / G o / P y t h o n / R u s t / J s / T s Cpp/Go/Python/Rust/Js/Ts Cpp/Go/Python/Rust/Js/Ts
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;class Node
{
public:int val;Node *pre;Node *next;Node() : val(0), pre(nullptr), next(nullptr) {}Node(int val) : val(val), pre(nullptr), next(nullptr) {}Node(int val, Node *pre, Node *next) : val(val), pre(pre), next(next) {}
};Node *la()
{Node *c = new Node(2);Node *b = new Node(1);Node *a = new Node(0);a->next = b;b->next = c;c->pre = b;b->pre = a;return a;
}void la_check(Node *h)
{vector<int> ans;Node *iter = h;while (iter){ans.push_back(iter->val);iter = iter->next;}if (ans.size() != 3){throw new runtime_error("size");}if (ans[0] != 2){throw new runtime_error("0");}if (ans[1] != 1){throw new runtime_error("1");}if (ans[2] != 0){throw new runtime_error("2");}
}Node *lb()
{return new Node(5);
}void lb_check(Node *h)
{if (h == nullptr){throw new runtime_error("h null");}if (h->val != 5){throw new runtime_error("val");}
}Node *reverse(Node *h)
{Node *pre = nullptr;Node *iter = h;while (iter){Node *next = iter->next;iter->next = pre;iter->pre = next;pre = iter;iter = next;}return pre;
}int main()
{Node *l = la();Node *r = reverse(l);la_check(r);Node *l2 = lb();Node *rb = reverse(l2);lb_check(rb);Node *lnull = nullptr;if (reverse(nullptr)){throw new runtime_error("lnull");}cout << "ok" << endl;
}
# python
def main():l = la()r = reverse(l)la_check(r)l = lb()r = reverse(l)lb_check(r)l = Noner = reverse(l)if r is not None:raise Exception("error")print("ok")class Node(object):def __init__(self, val):self.val = valself.pre = Noneself.next = Nonedef la():c=Node(2)b=Node(1)a=Node(0)a.next = bb.next = cc.pre = bb.pre = areturn adef la_check(h):ans = []cur = hwhile cur:ans.append(cur.val)cur = cur.nextif ans != [2,1,0]:raise Exception("error")def lb():return Node(5)def lb_check(h):if h.val != 5:raise Exception("error")if h.next is not None:raise Exception("error")if h.pre != None:raise Exception("error")def reverse(h):pre = Nonecur = hwhile cur:next = cur.nextcur.next = precur.pre = nextpre = curcur = nextreturn preif __name__ == "__main__":main()
// rust
use std::cell::RefCell;
use std::rc::Rc;#[derive(Debug)]
struct Node {val: i32,prev: Option<Rc<RefCell<Node>>>,next: Option<Rc<RefCell<Node>>>,
}impl Node {fn new(val: i32) -> Self {Node {val,prev: None,next: None,}}
}fn la() -> Option<Rc<RefCell<Node>>> {let c = Rc::new(RefCell::new(Node::new(2)));let b = Rc::new(RefCell::new(Node::new(1)));let a = Rc::new(RefCell::new(Node::new(0)));a.borrow_mut().next = Some(b.clone());b.borrow_mut().next = Some(c.clone());c.borrow_mut().prev = Some(b.clone());b.borrow_mut().prev = Some(a.clone());Some(a)
}fn la_check(h: Option<Rc<RefCell<Node>>>) {let mut iter = h;let mut ans = Vec::new();while let Some(node) = iter {ans.push(node.borrow().val);iter = node.borrow().next.clone();}if ans.len() != 3 {panic!("length is not 3");}if ans[0] != 2 {panic!("0 error");}if ans[1] != 1 {panic!("1 error");}if ans[2] != 0 {panic!("2 error");}
}fn lb() -> Option<Rc<RefCell<Node>>> {Some(Rc::new(RefCell::new(Node::new(5))))
}fn lb_check(h: Option<Rc<RefCell<Node>>>) {let mut iter = h;let mut ans = Vec::new();while let Some(node) = iter {ans.push(node.borrow().val);iter = node.borrow().next.clone();}if ans.len() != 1 {panic!("length is not 1");}if ans[0] != 5 {panic!("0 error");}
}fn reverse(h: Option<Rc<RefCell<Node>>>) -> Option<Rc<RefCell<Node>>> {let mut cur = h;let mut pre: Option<Rc<RefCell<Node>>> = None;while let Some(node) = cur {let next = node.borrow_mut().next.take();node.borrow_mut().next = pre;node.borrow_mut().prev = next.clone();pre = Some(node);cur = next}pre
}fn main() {let l = la();let r = reverse(l);la_check(r);let l = lb();let r = reverse(l);lb_check(r);let l: Option<Rc<RefCell<Node>>> = None;let r = reverse(l);if r.is_some() {panic!("r is not None");}println!("ok");
}
function main() {let l = la();let r = reverse(l);la_check(r);l = lb();r = reverse(l);lb_check(r);r = reverse(null);if (r) {throw new Error("lnull error")}console.log("ok")
}class ListNode {val: number;prev: ListNode | null;next: ListNode | null;constructor(val: number) {this.val = val;this.prev = null;this.next = null;}
}function la(): ListNode | null {const c = new ListNode(2);const b = new ListNode(1);const a = new ListNode(0);a.next = b;b.next = c;c.prev = b;b.prev = a;return a;
}function la_check(h: ListNode | null) {let ans: number[] = [];let iter: ListNode | null = hwhile (iter) {ans.push(iter.val);iter = iter.next;}if (ans.length != 3) {throw new Error("length error")}if (ans[0] != 2) {throw new Error("0 error")}if (ans[1] != 1) {throw new Error("1 error")}if (ans[2] != 0) {throw new Error("2 error")}
}function lb(): ListNode | null {return new ListNode(5);
}function lb_check(h: ListNode | null) {if (!h) {throw new Error("h null error")}if (h.val != 5) {throw new Error("5 error")}if (h.next) {throw new Error("next error")}if (h.prev) {throw new Error("prev error")}
}function reverse(h: ListNode | null): ListNode | null {let iter: ListNode | null = h;let prev: ListNode | null = null;while (iter) {let next = iter.next;iter.next = prev;iter.prev = next;prev = iteriter = next}return prev
}main();
相关文章:
【算法】009、单双链表反转
【算法】009、单双链表反转 文章目录 一、单链表反转1.1 实现思路1.2 多语言解法 二、双链表反转2.1 实现思路2.2 多语言解法 一、单链表反转 1.1 实现思路 维护 pre 变量。 从前向后遍历 head,首先记录 next head.next,其次反转指针使 head.next pr…...
物联网设备接入系统后如何查看硬件实时数据?
要在软件中实时查看硬件设备的信息,通常需要结合前后端技术来实现。以下是设计思路和实现步骤: 1. 系统架构设计 实时查看硬件设备信息的系统通常采用以下架构: 数据采集层: 硬件设备通过传感器采集数据,发送到InfluxDB。数据存…...
【Linux系统编程】初识系统编程
目录 一、什么是系统编程1. 系统编程的定义2. 系统编程的特点3. 系统编程的应用领域4. 系统编程的核心概念5. 系统编程的工具和技术 二、操作系统四大基本功能1. 进程管理(Process Management)2. 内存管理(Memory Management)3. 文…...
解决stylelint对deep报错
报错如图 在.stylelintrc.json的rules中配置 "selector-pseudo-class-no-unknown": [true,{"ignorePseudoClasses": ["deep"]} ]...
React基础之useInperativehandlle
通过ref调用子组件内部的focus方法来实现聚焦 与forwardRef类似,但是forwardRef是通过暴露整个Ref来实现,而useInperativehandle是通过对外暴露一个方法来实现的 import { forwardRef, useImperativeHandle, useRef, useState } from "react";…...
使用joblib 多线程/多进程
文章目录 1. Joblib 并行计算的两种模式多进程(Multiprocessing,适用于 CPU 密集型任务)多线程(Multithreading,适用于 I/O 密集型任务)2. Joblib 的基本用法3. Joblib 多进程示例(适用于 CPU 密集型任务)示例:计算平方4. Joblib 多线程示例(适用于 I/O 密集型任务)…...
⭐算法OJ⭐N-皇后问题 II【回溯剪枝】(C++实现)N-Queens II
⭐算法OJ⭐N-皇后问题【回溯剪枝】(C实现)N-Queens 问题描述 The n-queens puzzle is the problem of placing n n n queens on an n n n \times n nn chessboard such that no two queens attack each other. Given an integer n, return the num…...
【数据结构初阶】---堆的实现、堆排序以及文件中的TopK问题
1.树的概念及结构 1.1树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点&…...
ubuntu20系统下conda虚拟环境下安装文件存储位置
在 Conda 虚拟环境中执行 pip install 安装软件后,安装的文件会存储在该虚拟环境专属的 site-packages 目录中。具体路径取决于你激活的 Conda 环境路径。以下是定位步骤: 1. 确认 Conda 虚拟环境的安装路径 查看所有环境: conda info --env…...
鸿蒙开发:RelativeContainer 相对布局详解【全套华为认证学习资料分享(考试大纲、培训教材、实验手册等等)】
前言 在最新版本的 DevEco Studio 中,官方在创建新项目时,默认使用 RelativeContainer 组件作为根布局。这足以证明 RelativeContainer 的重要性。相比其他容器组件,它极大地简化了复杂 UI 布局中的元素对齐问题。 例如,在没有 R…...
基于SpringBoot实现旅游酒店平台功能一
一、前言介绍: 1.1 项目摘要 随着社会的快速发展和人民生活水平的不断提高,旅游已经成为人们休闲娱乐的重要方式之一。人们越来越注重生活的品质和精神文化的追求,旅游需求呈现出爆发式增长。这种增长不仅体现在旅游人数的增加上࿰…...
HttpServletRequest 和 HttpServletResponse 区别和作用
一、核心作用对比 对象HttpServletRequest(请求对象)HttpServletResponse(响应对象)本质客户端发给服务器的 HTTP 请求信息(输入)服务器返回客户端的 HTTP 响应信息(输出)生命周期一…...
树莓派学习(一)——3B+环境配置与多用户管理及编程实践
树莓派学习(一)——3B环境配置与多用户管理及编程实践 一、实验目的 掌握树莓派3B无显示器安装与配置方法。学习Linux系统下多用户账号的创建与管理。熟悉在树莓派上使用C语言和Python3编写简单程序的方法。 二、实验环境 硬件设备:树莓派…...
Mysql安装方式
方式一:安装包安装 下载安装包 官网直接下载:https://dev.mysql.com/downloads/ 安装配置 2.1、双击刚刚下载好的msi文件,开始安装MySQL。 2.2、选择自定义模式Custom安装 2.3、点击选择自己电脑对应的mysql安装目录 2.5、继续点击下一步&…...
Vue3实战学习(Vue3的基础语法学习与使用(超详细))(3)
目录 (1)Vue3工程环境准备、项目基础脚手架搭建详细教程。(博客链接) (2)Vue3的基础语法学习与使用。 (1)"{{}}"绑定数据。 <1>ref()函数定义变量——绑定数据。 <2>reactive({...})…...
使用websocket,注入依赖service的bean为null
问题:依赖注入失败,service获取不到,提示null 这是参考代码 package com.shier.ws;import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.google.gson.Gson; import com.s…...
批量在 Word 的指定位置插入页,如插入封面、末尾插入页面
我们经常会碰到需要在 Word 文档中插入新的页面的需求,比如在 Word 文档末尾插入一个广告页、给 Word 文档插入一个说明封面,在 Word 文档的中间位置插入新的页面等等。相信这个操作对于大部分小伙伴来说都不难,难的是同时给多个 Word 文档插…...
算法系列之滑动窗口
算法系列之滑动窗口 题目 给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1:输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2:输入: s "bbbbb"…...
【C#】详解C#中的内存管理机制
文章目录 前言一、C#内存管理的基本机制(1)托管堆(Managed Heap)(2)垃圾回收(Garbage Collection)(3)栈内存 二、 开发者需要主动管理的场景(1&am…...
C/S架构与B/S架构
一、定义与核心区别 C/S架构(Client/Server,客户端/服务器) 客户端需安装专用软件(如QQ、企业ERP系统),直接与服务器通信。服务器端通常包括数据库和业务逻辑处理1。特点:客户端承担部分计算任务…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
