Airtest iOS测试环境部署

简介

这个Airtest IDE是通过iOS-Tagent来操作iPhone的,你可以在Airtest IDE里录制脚本来实现自动化操作iPhone

前提

1. 得有个iOS开发者账号,然后才能在developer.apple.com的account下看到管理自己的证书入口,否则看不到

2. 将要下载的iOS-Tagent需要在xcode里启动,所以要保证iPhone连接的mac电脑上安装了xcode

3. 下载iOS-Tagent:https://github.com/AirtestProject/IOS-Tagent,这个readme上的步骤下文会用到

4. 下载Airtest IDE:http://airtest.netease.com/,看下官方中文文档,其中2.4章节关于iOS设备连接的方法下文会用到

部署步骤

1. 按github上的reademe启动iOS-Tagent,这样iPhone就和iOS-Tagent连接上了

2. 启动Airtest IDE并connect device(注意填入的ip和端口号要和xcode中iOS-Tagent server的ip地址和端口号一致)

遇到的问题

1. 如果遇到了让你输入登录钥匙密码的问题,记得点击始终允许,否则就会一直让你重复的输密码

2. 如果出现证书校验出错了相关的问题,在developer.apple.com的account下进入证书管理页,把之前的证书删掉,然后在xcode里就会重新生成一个

3. 涉及到删证书的操作,除了在开发者网站上删除证书,还要在本地删除provision文件:

cd ~/Library/MobileDevice/Provisioning\ Profiles/
rm *.mobileprovision

4. 真机安装好WebDriverAgent app后可能需要在手机上信任下安装的app

5. 在xcode下将iOS-Tagent test起来之后再在AirtestIDE里录脚本,看xcode日志输出在底部栏*左边按钮-Show the Debug Area

6. 在xcode的Debug Area中搜索ServerUrlHere关键词可以看到iOS-Tagent server的ip地址和端口号

airtest连接IOS设备过程记录

话不多说,直接步入正题,鉴于可能有从零开始的同学,所以这里的步骤可能写的繁琐了点~

步骤一(前期准备)
首先你得有个IOS手机,MAC电脑,Airtest IDE,以及基础的一些环境
Airtest官方的基本要求

版本需求:
Mac Xcode ≥ 9.3
iPhone iOS ≥ 9.3
在 9.3≤iOS≤10时,由于基于旧版xcode SDK,建议使用Xcode 版本≤10.1来启动iOS-Tagent,否则会出现手机截屏不全的问题。
Airtest是基于Python的,支持版本2.7或≤3.6,官方推荐使用3

Airtest下载地址
Xcode下载地址 这里给出的是官方的历史版本下载地址,从app store下载*新版本的xcode会存在一些问题
IOS-Tagent下载地址 使用git clone或者直接下载zip解压都可以
iproxy工具,做端口转发需要,具体安装方式使用brew install libimobiledevice即可

步骤二
使用Xcode打开步骤一中的IOS-Tagent项目,然后需要一些具体设置,详细的设置步骤可以参考我的上过一篇文章,上文中的步骤三开始到*后都与此处操作一致

关于Xcode版本
*终我使用成功的版本为Xcode10连接,IOS12.3以及IOS12.3.1设备
官方的IOS-Tagent说明的测试过版本为

IOS XCode
≥13 11.x
10.x~12.x 10.x
≥9.3 ≥9.3
关于高版本Xcode的操作经历
一开始不服,从app store直接下载了*新的Xcode11.5,使用IOS-Tagent,项目连启动都失败,执行Product -> Test过程中遇到了其他问题
仍然不服,于是想试试facebook的WebDriverAgent,毕竟IOS-Tagent是基于这个改造的,于是也就有了上篇文章WebDriverAgent踩坑-Xcode11.5
稍微不服,考虑到IOS-Tagent中在*次尝试时报错的位置是WebDriverAgentLib中的问题,而我在第二次尝试也就是上篇文章中成功通过WebDriverAgent连接了IOS设备,于是我就将IOS-Tagent中相关内容替换成了2中也就是上一篇文章中运行成功后的产物,也就是这部分文件

%title插图%num

替换之后项目果然能够成功运行(向前前进了一大步),但是还是无法连接到Airtest IDE,也没有任何明确的报错信息
不服不行了。。去步骤一中下载了Xcode10,然后继续搞起
Xcode10使用过程中遇到的问题
本机已经有了一个Xcode了,如何安装第二个
首先到步骤一中提供的网址下载对应的xip安装包,下载好后双击就会自动验证+解压(保证磁盘空间充足才行,否则自动验证步骤失败)
然后,将解压出来的Xcode.app重命名为Xcode10.app或其他名字,不冲突即可,拖入Application中
如何让Xcode10支持高版本的IOS设备
官方提供的经测试范围是Xcode 10.x可以操作IOS10.x~12.x之间的版本,我下周的版本是Xcode10,没有小版本,*高只能支持IOS12的操作,但是我的IOS设备室

12.3和12.3.1的,所以需要额外的操作

这就需要用到之前下载的高版本Xcode11.5了,
进入之前的应用包中如下位置:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport,可以看到很多版本号的数字,代表IOS版本,把你需要的包整个文件夹拷贝到对应的你需要使用的Xcode中,例如我需要拷贝到/Applications/Xcode10.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/中
重新启动Xcode10

步骤三
项目启动成功后使用iproxy做端口转发:iproxy 8100 8100,成功即可在浏览器中http://127.0.0.1/status看到一个json串,在http://127.0.0.1/inspector中看到手机屏幕的投影。注意此处与上篇文章中的区别,上篇文章中使用的是Xcode11.5,由于版本问题,所以上篇文章中即使链接成功了也不能在浏览器中看到手机屏幕的投影,而此次能够看到:

%title插图%num
步骤四
也是*后一步,在Airtest IDE中点击点击连接按钮即可连接上IOS设备了,终于可以愉快地直接截图操作了

%title插图%num
步骤五
终于大功告成,可以happy一下了

步骤六
继续写用例

iOS 13 SceneDelegate适配

Xcode 11新建工程
在Xcode 11 创建的工程,运行设备选择 iOS 13.0 以下的设备,运行应用时会出现黑屏现象。
原因:

Xcode 11 默认是会创建通过 UIScene 管理多个 UIWindow 的应用,工程中除了 AppDelegate 外会多一个 SceneDelegate
AppDelegate和SceneDelegate这是iPadOS带来的新的多窗口支持的结果,并且有效地将应用程序委托的工作分成两部分。
也就是说在我们用多窗口开发iPadOS中,从iOS 13开始,您的应用代表应该:

设置应用程序期间所需的任何数据。
响应任何专注于应用的事件,例如与您共享的文件。
注册外部服务,例如推送通知。
配置您的初始场景。
相比之下,在iOS 13中的新顶级对象是一个UIWindowScene,场景代表可以处理应用程序用户界面的一个实例。因此,如果用户创建了两个显示您的应用程序的窗口,则您有两个场景,均由同一个应用程序委托支持。
这些场景旨在彼此独立工作。因此,您的应用程序不再移动到后台,而是单个场景执行 – 用户可以将一个移动到后台,同时保持另一个打开。

我们可以看下info.plist文件和工程项目文件的变化如图:

%title插图%num

适配方案一
如果我们不开发iPadOS多窗口APP,SceneDelegate窗口管理我们可以不需要直接删掉就好了。

删除掉info.plist中Application Scene Manifest选项,同时,文件SceneDelegate可删除可不删
相关代码注释掉

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: “Default Configuration”, sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
//注释掉这两个方法。

Appdelegate新增windows属性
var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//如果是用默认的storyboard,下面的代码可以不写
// window = UIWindow.init()
// window?.frame = UIScreen.main.bounds
// window?.makeKeyAndVisible()
// window?.rootViewController = UIStoryboard.init(name: “Main”, bundle: nil).instantiateInitialViewController()
return true
}
///做完这些就跟以前一样啦。

适配方案二
即要用iOS 13中新的SceneDelegate,又可以在iOS 13一下的设备中完美运行。那就添加版本判断,利用@available

步骤:

SceneDelegate中添加@available(iOS 13, *)
@available(iOS 13, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
//在类的头部@available(iOS 13, *)添加即可
……..
……..
…….
}

AppDelegate中同样声明window属性
var window: UIWindow?
///didFinishLaunchingWithOptions中添加版本判断
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 13, *) {
}else {
window = UIWindow.init()
window?.frame = UIScreen.main.bounds
window?.makeKeyAndVisible()
window?.rootViewController = UIStoryboard.init(name: “Main”, bundle: nil).instantiateInitialViewController()
}
return true
}

 

AppDelegate中两个关于Scene的类也添加版本控制,Swift中可以用扩展单独拎出来,如下:
@available(iOS 13.0, *)
extension AppDelegate {
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: “Default Configuration”, sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}
}

///完工

切记:这种方式,AppDelegate中的有关程序的一下状态的方法,iOS 13设备是不会走的,iOS13一下的是会收到事件回调的。13以上的设备会走SceneDelegate对应的方法

func applicationWillResignActive(_ application: UIApplication) {
}
…..
…..
…..

iphone换机数据迁移_IPHONE数据迁移到安卓系统操作分析:

a49ef93016cab0cf75e3ed1f63f28c99.png

一、2016年之前的系统:

由于IOS系统(ISO即苹果操作系统)的限制,未越狱的情况下,苹果公司是不允许用户过多的操作手机里的内容的,这也是IOS系统一直比安卓系统安全的主要原因。所以,在多数通用的APP软件里,比如“QQ同步助手”、百度云、移动的“和彩云网盘”、联通的“沃云盘”,在安卓系统下,都是可以备份通讯录、短信和通话记录的,但是在IOS系统里,只能备份通讯录一项,特别是短信这一项,则不能被访问,也就是说,在官方IOS系统里,用户无法自行备份短信和通话记录

在IOS11出现之前,苹果的越狱系统一直被大家追捧,原因就是越狱之后,用户是可以通过软件,对在原版IOS下无法操作的某些东西进行操控,比如短信备份。特别是在ISO9以及9之前,越狱后的IOS系统,通过“QQ同步助手PRO版”,可以直接备份短信,然后在安卓系统上,直接进行恢复,傻瓜式操作,没有什么技术含量了。后来由于苹果公司限制了越狱,多数的越狱软件不能运行,或是已经没有了这些软件,使得很多苹果用户在切换到安卓系统时遇到了*恶心的问题:就是短信无法迁移支安卓系统上。

二、2020年将ISO13的数据迁移到安卓机上。

2019年底购了一台华为P30 PRO,由于原来的手机IOS系统已经升级到12,不能越狱。就某度了一下有没有解决方案。遗憾的是,搜索出来的结果多数都是复制粘贴的,都是同一种说法,甚至有些根本不懂IOS系统的就在瞎侃,说怎么怎么操作就可以了,其实就是胡扯。

先后下载了几款软件进行备份,发现要么是收费,要么是忽悠,根本没有操作的可能。

其中多数软件提到了一款iSMS2droid的软件,用它可以将备份在电脑端的ISO文件选择恢复到安卓上。但是搜索之后,发现*新的华为系统、小米系统、魅族系统下,这款软件都由于权限,恢复短信时提示恢复失败。

经过近一周的反复测试,终于把苹果系统下的文件成功迁移到了华为手机上,现将操作流程分享一下:

准备工作:买一个转换头(如图);电脑端下载“爱思助手7.0”,安卓手机下载“i换机大师”。

d6c755953ad428ef4ad425d615b45080.png
01d54800291338d6a753e47c9dfe56c7.png
238f8dc0f9757172669482d2f75e8de5.png

1、 用爱思助手7.0备份系统。

备份系统,对于一个IT人员来说,是至关重要的,因为无论什么时候,操作失败的情总下,必须进行数据的恢复,毕竟,手机有价,数据无价,这个理论无论什么情况下都是成立的。

备份的时候,选择全部备份(因为没法子进行部分备份,备份的目录选择非C盘)。提前检查一下自己的苹果手机用了多少空间,一般备份前先把微信的临时空间清理一下,特别是群多的,尽管很多群聊天内容不看,但是也会占用一部分空间,比如我媳妇的手机,整理一下微信,花了一个多小时,清理了20个G的临时空间,这为后期的备份省去了好多时间。

备份的时候,会和ITNUES一样,提示设置密码。如果设置了itnues密码,请牢牢记住。以后要用。备份的原因,是为了恢复失败时,可以进行恢复。如果坚持认为手机没有重要的内容,可以忽略,也要准备承担恢复失败的心理准备。现在的电脑,配置高些的话,备份40个G的话,大概需要1-1.5个小时左右,电脑配置低的话,就照着2小时甚至更长的时间去准备吧。

2、 在华为手机上下载“i换机大师”

在华为手机上下载“i换机大师”。小米的官主应用上没有这个软件,需要自行在浏览器里去搜索下载。这个软件是在测试了近十款之后确定的。其它的虽然也能部分的恢复数据和短信,但是功能和速度上,比这个还是有很大差距的。

85d61f92208ed5b99ee80505e9a468d5.png
e03a0f4fbf6d8be8e4beaec537732fc6.png

3、 用数据线和转换头将苹果手机和华为手机连接

所有的准备工作就绪之后,就在安卓手机上进行操作了。

运行“i换机大师”,会显示两个选项“通过USB线导入”和“通过iCloud导入”。本人测试了,使用“通过iCloud导入”,没有短信这个选项,达不到自己的需求,所以忽略。

“通过USB线导入”,这个过程会需要一段时间,偶尔也会出现闪退的情况,之后就会出现自己非常期待的界面,希望恢复的内容几乎都在里面,有照片,有通讯录,有短信,甚至有备忘录,照片和视频,自行选择恢复就行了。操作的过程中,会提示输入itunes备份密码。如果忘记密码的话,没法子,按照提示,将手机恢复默认设置才能解决(本人测试的,即使恢复默认设置,安卓端依然会提示输入密码,*后只得将恢复系统之后无密码的情况再用爱思助手备份一次之后,才不会提示输入密码的选项)。

提示:

1、 在WINDOWS下备份苹果系统时,会提到一个加密问题,在用ITNUES备份时,也是有这个选项的。友情提示,这个密码必须牢牢记住,否则后期非常的麻烦。

2、 即使提示你已经完全恢复成果,也不要全信它。自己再在两部手机中检测一下,看是否真的将全部数据导入过来。我*次系统提示成功,但是检测后发现通讯录少了300多个电话;第二次导入后再验证,电话才成功,但是短信的某些日期与实际不符。第三次才算成功。具体的情况,大家自已体验吧。

ios系统软件迁移到安卓_换机无烦恼 iOS和安卓数据相互迁移

由于系统的不同,Android和iOS直接的数据迁移一直是跨系统换机用户的一个头疼事。加之iOS系统相对没安卓系统开放,数据的互传也一直较为繁琐。然而云端备份恢复、第三方软件备份成为了跨平台数据迁移的一个重要桥梁。本文中笔者将为大家分享一些简单的备份技巧,让iOS与Android数据迁移不再是难事。

手机的数据迁移无非包括以下几方面:通讯录、短信、照片、视频,下面具体了解一下:

iOS与Android照片/视频互导

工具/软件:

豌豆荚(或者其他同类型软件)、iTools(或者其他同类型软件)

方法/步骤:

1.手机的连接和环境准备

将你的Android手机用数据点与电脑连接,并且,确认“USB调试”已经打开(不懂怎么打开可参考//product.pconline.com.cn/itbk/sjtx/Android44/1502/6148396.html),手机驱动已经安装完毕,手机已“允许本机调试”。

2.打开电脑上的豌豆荚,豌豆荚会提示手机已经与电脑连接;如果显示未连接,有可能是驱动没有安装成功,重新拔插手机,让电脑自动安装手机驱动(或进入您手机的品牌官网下载对应驱动安装),如果还是不行,注意重新检查手机是否已经允许电脑调试。

3.导出安卓设备中的照片/视频

点击左栏“我的照片”,勾选需要导出的照片/视频,并且点击“导出”,选择导出路径即可。如图:

4.把照片/视频导入iOS设备中

将iOS设备用数据线与电脑连接,iTools会提示是否连接(请确认已经安装iTunse),在左栏点击“照片管理”;然后点击“导入”,选择导入照片存储路径,选择照片点击“确定”,等待片刻,照片就导入到iOS设备中了。如图:

注:iOS导入至安卓同理逆向操作

iOS与Android通讯录互导

工具/软件:

微信或QQ同步助手

方法/步骤:(以微信为例)

1.iOS/Android打开微信 > 我 > 设置 > 通用 > 功能 > 通讯录安全助手 > 进入安全助手 > 备份

2.iOS/Android打开微信 > 我 > 设置 > 通用 > 功能 > 通讯录安全助手 > 进入安全助手 > 恢复

编后语:尽管iOS与Android属于不同平台,但随着云端服务越来越普遍,跨平台也成为了家常便饭。数据的迁移不再是难事。当然鉴于民用的电信网络上行速率有限,备份大体积的数据比较耗时不是特别现实,大体积的数据还是建议使用PC软件通过本地环境进行备份比较靠谱。

 

IOS解决闪屏无效LuanchImage启动动画设置加载广告闪屏图

IOS闪屏动画LuanchImage设置无效
设置Launch Image无效
其它方法
转载请标明出处:
本文出自:【奥特曼超人的博客】

设置Launch Image无效
设置无效,按照网上办法是:
在 Image.xcasset 中 new 一个 IMAGE SET,再更名:Launch Image ,感觉文章复制的人有点多,大部分都是这种,其它方法也是无效的,*后发现修改 info.list + build setting 配置才能生效。

其它方法
*步 :创建ios launch image(deprecated) ,代码中有设置图片闪屏的可以忽略,注意,刚更新XCODE的创建位置不一样了,如下图。

%title插图%num

第二步 :创建完后,会自动勾选所有,目前适配的是 Iphone,Ipad 可以忽略,所以可以去掉勾选,再根据对应的尺寸拖进去就好了。

%title插图%num
这里注意,网上说把Launch Screen File去掉,其实不去掉也可以,等会info.list操作后也会自动清空的,如下图。

%title插图%num

第三步 : 然后我们打开 info.list , 找打 Launch screen interface file base name ,直接把值去掉,然后添加一行,key设置为 Launch Image ,value 设置为定义的名字,这里设置的是 LaunchImage。

第四步 :打开 Build Settings , 搜索 Asset Catalog Launch Image Set Name ,然后把值设置为新建的图片名字即可,设置设置的是LaunchImage。

第五步 :直接编译 command + B ,如果编译失败检查这里的配置,如下图。

%title插图%num

gg修改器ios版下载

gg修改器ios版下载
推荐一个修改器下载站www.miaozan.art

GameGuardian iOS – 您是否花费数月时间尝试玩游戏的所有阶段?您不想花钱达到*好的阶段吗?然后,游戏改装是您的*佳选择。您可以修改任何游戏以赚取无限的硬币,宝石或游戏中的任何东西。有许多适用于智能手机设备的改装应用程序。今天,我们将讨论iOS设备上的改装

Game Guardian APK是适用于Android设备的改装应用程序,可让您免费修改自己喜欢的任何游戏。现在,您可以在Game Guardian应用程序的帮助下赚取无限的金币,积分,宝石,不同的化身。您可以通过Game Guardian进入任何游戏阶段。您无需花费数月的时间来尝试清理阶段即可享受*后一个阶段。游戏的每个付费设施都可以一键点击。

可以使用GameGuardian App轻松修改地铁冲浪者,医生驾驶,忍者奔跑,神庙逃亡,沥青8和爬坡赛车等游戏。如果您尝试修改《部落冲突》等在线游戏,可能会被禁止。您可以借助GameGuardian进入任何游戏的任何级别。今天,我们将讨论如何在iPhone设备上下载并安装GameGuardian iOS App。

%title插图%num

下载GameGuardian iOS 10

建议使用Cydia Package Manager在您的iPhone设备上安装GameGuardian App。GameGuardian应用程序支持iOS 5.0或更高版本。请按照以下步骤在您的iPhone设备上安装GameGuardian。

您将必须在iOS设备上安装Cydia。越狱iPhone设备后,您可以安装Cydia软件包管理器。Cydia软件包管理器可让您免费在iPhone设备上安装所有改装应用程序。请按照以下步骤在您的iPhone设备上下载iGameGuardian

1, 在iPhone设备上打开Cydia应用程序。

2, 转到“源”,然后选择“ Big Boss”回购。

3 ,现在搜索“ GameGuardian App”。

4,开始下载GameGuardian App,然后将其安装在您的iPhone设备上。

5 , 点击上GameGuardian图标来启动应用程序。

141. 环形链表(JS实现)141. 环形链表(JS实现)

环形链表(JS实现)

PAT-python-zjw 2020-08-04 19:56:51 328 收藏
分类专栏: 剑指offer
版权
1 题目
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到*个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?

2 思路
这道题的主要思路快慢两个指针遍历整个链表,如果两者相遇则表示链表有环

3代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function(head) {
if (!head) return false;
let stepOne = head;
let stepTwo = head;

while(stepOne && stepTwo) {
stepOne = stepOne.next;
stepTwo = stepTwo.next && stepTwo.next.next;
if (stepOne && stepOne === stepTwo) return true;
}

return false;
};

环形链表 II(JS实现)

环形链表 II(JS实现)

1 题目
给定一个链表,返回链表开始入环的*个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:tail connects to node index 0
解释:链表中有一个环,其尾部连接到*个节点
示例 3:
输入:head = [1], pos = -1
输出:no cycle
解释:链表中没有环。
进阶:
你是否可以不用额外空间解决此题?

2 思路
题解中的floyed算法

3代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/

/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if (!head) return null;

let slow = head, fast = head;

while(fast && slow) {
slow = slow.next;
fast = fast.next && fast.next.next;
if (fast && slow === fast) {
let meetPoint = slow;
while (meetPoint) {
if (meetPoint === head) return meetPoint;
meetPoint = meetPoint.next;
head = head.next;
}
}
}

return null;
};

重排链表(JS实现)

重排链表(JS实现)

1 题目
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

2 思路
这道题的主要思路首先遍历一次链表获取整个链表长度,并将节点存储在数组中,再按题目要求连接链表,注意链表长度的奇偶不同时,*后一个节点的处理不同。题解中还有一种反转后半部分链表的解法。
1、先找处链表L的中间结点,为此设置两个指针p和q,指针p每次走一步,指针q每次走两步,当指针q到达链尾时,指针p正好在链表的中间结点;
2、然后将L的后半段结点原地逆置;
3、从单链表前后两段中 依次各取一个结点,按要求重排;

3代码
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {void} Do not return anything, modify head in-place instead.
*/
var reorderList = function(head) {
if (!head || !head.next || !head.next.next) return head;
const arr = [];

let len = 0;
while(head) {
arr[len] = head;
len++;
head = head.next;
}

let l = Math.floor(len/2);
for (let i=0; i<l; i++) {
if (i !== l -1 || len % 2 !== 0) {
arr[len – i – 1].next = arr[i].next;
arr[i].next = arr[len-i-1];
}

if (i === l – 1) { //*后一个节点
if (len % 2 !== 0) {
arr[len – i – 1].next.next = null;
} else {
arr[i].next.next = null;
}
}
}
};