模块

  时间模块:time/datatime/calendar。

  系统操作文件模块:os

time模块

  • 介绍
  1. import time
  2.  
  3. # 获取当前时间, 结果是存在时间元组中的。星期一是从0开始的
  4. # 结果:time.struct_time(tm_year=2019, tm_mon=8, tm_mday=22, tm_hour=18, tm_min=21, tm_sec=46, tm_wday=3, tm_yday=234, tm_isdst=0)
  5. c_time = time.localtime()
  6. print(c_time)
  7.  
  8. # 获取时间元组中指定的时间。比如 年
  9. year = c_time[0]
  10. print(year)
  11. # 获取时间元组中指定的时间。比如 年。根据时间元组中指定的时间字段获取
  12. year = c_time.tm_year
  13. print(year)
  14.  
  15. # 获取时间戳。指定时间对应的秒数。当前时间对应的时间戳
  16. now = time.time()
  17. print(now)
  18.  
  19. # 时间格式化。占位格式:
  20. """
  21. 格式化时间的占位符:
  22. %Y ---- 年
  23. %m --- 月
  24. %d ---- 日
  25. %H ---- 24小时制
  26. %I ----- 12小时制
  27. %p ---- 标记上下午
  28. %M --- 分
  29. %S ---- 秒
  30. %w --- 星期
  31. %j ----- 一年中的第几天
  32. %z ---- 时区
  33. """
  34. # 将时间元组格式转为指定时间格式
  35. str_time = time.strftime("%Y-%m-%d %H:%M:%S",c_time)
  36. print(str_time)
  37.  
  38. # 将指定的时间格式转化为时间元组
  39. time_string = time.strptime(str_time,"%Y-%m-%d %H:%M:%S")
  40. print(time_string)
  41.  
  42. # 获得自定义时间的时间戳
  43. c_time = time.mktime(time_string)
  44. print(c_time)
  45.  
  46. # 将时间戳转换为时间元组
  47. time_str = time.localtime(c_time)
  48. print(time_str)
  • 练习
  1. """
  2. 题干:
  3. 指定时间:"2018-10-22 121512"
  4. 在这个时间基础上,获取三天后的时间 "2018-10-25 121512"
  5.  
  6. 解决:
  7. 1。指定时间 --- 时间元组
  8. 2。时间元组 --- 时间戳
  9. 3。时间戳 + 3天的秒数
  10. 4。新时间戳 --- 时间元组
  11. 5。新时间元组 --- 格式化时间
  12. """
  13. import time
  14. def get_time(src_time):
  15. time_tuple = time.strptime(src_time,"%Y-%m-%d %H:%M:%S") # 指定时间 变 时间元组
  16. c_time = time.mktime(time_tuple) # 时间元组 变 时间戳
  17. new_time = c_time + 3 * 24 * 60 * 60 # 时间戳 + 3 天
  18. new_time_tuple = time.localtime(new_time) # 时间戳 变 时间元组
  19. time_str = time.strftime("%Y-%m-%d %H:%M:%S",new_time_tuple)# 时间元组 格式时间
  20. return time_str
  21.  
  22. if __name__ == '__main__':
  23. res = get_time("2018-10-22 13:15:12")
  24. print(res)

datetime模块

  • 介绍
  1. import datetime
  2.  
  3. # 获取当前时间。 结果:2019-08-22 19:19:21.842469
  4. c_time = datetime.datetime.now()
  5. print(c_time)
  6.  
  7. # 获取日期。结果:2019-08-22
  8. d_time = datetime.date.today()
  9. print(d_time)
  10.  
  11. # 获取当前时间对应的星期。 结果:3。表示星期四
  12. w_time = c_time.weekday()
  13. print(w_time)
  14.  
  15. # 获取年、月、日。 结果:2019
  16. y_time = c_time.year
  17. print(y_time)
  18.  
  19. # 自定义时间。 结果:2018-03-23 00:00:00。时分秒没传默认是零,年月日必须传值
  20. p_time = datetime.datetime(year=2018,month=3,day=23)
  21. print(p_time) # 类型:datetime.datetime
  22.  
  23. # 获取指定时间的几天后的时间。结果:2018-03-26 00:00:00
  24. d_time = p_time + datetime.timedelta(days=3)
  25. print(d_time) # 类型:datetime.datetime
  26.  
  27. # 格式化时间:年/月/日 时 分 秒。结果:字符串类型,2018/03/23 00 00 00
  28. f_time = p_time.strftime("%Y-%m-%d %H:%M:%S")
  29. print(f_time) # 类型:str
  30.  
  31. # 反格式化时间
  32. r_time = datetime.datetime.strptime(f_time,"%Y-%m-%d %H:%M:%S")
  33. print(r_time) # 类型:datetime.datetime
  34. print(type(r_time))
  35.  
  36. # 使用运算符 "—"。 计算两个时间的时间差. 结果:355 days, 0:00:00
  37. fr_time = datetime.datetime(2017,12,31)
  38. se_time = datetime.datetime(2018,12,21)
  39. diff = se_time - fr_time
  40. print(diff)
  41.  
  42. # 获取相差天数。 结果:355
  43. days = diff.days
  44. print(days)
  45.  
  46. # 获取时间差差异的秒数。 结果:30672000.0
  47. tol = diff.total_seconds()
  48. print(tol)
  49.  
  50. # 获取后面时分秒结合起来的秒数,不包括前面的天数。 结果:0
  51. res = diff.seconds
  52. print(res)

calendar模块

  • 方法
  1. import calendar # 1900年起始
  2.  
  3. # 获取指定年的日历
  4. y_calendar = calendar.calendar(2018)
  5. print(y_calendar)
  6.  
  7. # 获取指定年 指定月的日历
  8. m_calendar = calendar.month(2017,12)
  9. print(m_calendar)
  10.  
  11. # 判断该年是否是闰年。 结果:True
  12. is_leap = calendar.isleap(2000)
  13. print(is_leap)
  14.  
  15. # 获取指定月对应中 把星期作为分割点,一个星期为一个小列表存放在一个大列表中。前面没有数据的话,用零占位。
  16. # 结果:[[0, 0, 0, 0, 0, 1, 2], [3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30], [31, 0, 0, 0, 0, 0, 0]]
  17. res = calendar.monthcalendar(2018,12)
  18. print(res)
  19.  
  20. # 获得某天对应的星期。 结果:3 表示 星期4
  21. week = calendar.weekday(2018,1,4)
  22. print(week)

os模块

  • 方法
  1. import os
  2.  
  3. """
  4. 相对路径:当前文件所在的目录为参照,
  5. 如果指定文件的路径与参照文件在同一个目录下,获取其相对路径时,直接写文件名即可。
  6. 如果指定文件路径与参照路径不在同一个目录下,起始查找位置是当前文件
  7. 绝对路径:从具体的盘符开始,到指定的文件的路径。 .. 表示上一级;. 表示当前级
  8. """
  9. # 获取当前文件所在的相对目录。dir,文件夹目录的意思
  10. c_path = os.curdir
  11. print(c_path) # 结果:.
  12.  
  13. # 获取当前文件的绝对路基。结果:/Users/guoyapeng/pyword/python_start/day12_模块
  14. a_path = os.getcwd()
  15. print(a_path)
  16.  
  17. # 获取系统环境变量。结果:environ({'PATH': '/Users/guoyapeng/anaconda3/bin:、、、、、
  18. envir = os.environ
  19. print(envir)
  20.  
  21. # 获取指定环境变量下某个变量的值。结果:/Users/guoyapeng/anaconda3/bin/conda
  22. path_value = os.environ.get("CONDA_EXE")
  23. print(path_value)
  • 目录操作
  1. # 目录操作
  2.  
  3. # 相对路径创建目录。 如果参数只有一个文件夹名的话,默认与当前文件夹平级。如果目录已经存在,就会报错。
  4. os.mkdir("new_dir")
  5.  
  6. # 相对路径,在当前级别的上一级创建
  7. os.mkdir(r"../test1")
  8.  
  9. # 绝对路径创建,只能创建最后一级,前面没有相应的目录的话会报错
  10. os.mkdir(r"/Users/guoyapeng/pyword/python_start/text")
  11.  
  12. # 绝对路径创建,只能创建最后一级,前面没有响应的目录的话会会被创建出来
  13. os.mkdir(r"/Users/guoyapeng/pyword/python_start/text/text/text/text")
  14.  
  15. # 删除目录。 删除目录时只能删除空目录,目录中有内容不可删除
  16. os.rmdir(r"/Users/guoyapeng/pyword/python_start/text/text/text/text")
  17.  
  18. # 获得目录下的直接子文件、子目录,结果是列表类型的,列表中存放的是子文件的名字
  19. sub_list = os.listdir(r"..")
  20. print(sub_list)
  • 文件操作
  1. # 文件操作
  2. # 打开或者创建文件
  3. """
  4. open()方法:会返回一个操作文件的手柄,通过手柄操作文件指针进行文件读写
  5. 第一个参数:要进行操作文件的路径,在程序中的文件做好使用相对路径
  6. 第二个参数:操作文件的模式,读、写。。。
  7. r --- 表示的是只读。如果文件路径不存在,会报错
  8. w --- 表示的是只写。如果文件不存在,会创建文件;文件存在,会将文件中的内容清空
  9. a --- 表示的是只写。如果文件不存在,会创建文件;文件存在,将新写入的内容拼接在原有内容的后面
  10. r/w/a --- 表示操作的是字符数据
  11. r+/w+/a+ --- 可读可写
  12. rb --- b 表示二进制,加b表示操作的是字节数据
  13. rb+/wb+/ab+ --- 以二进制形式可读可写
  14. 第三个参数:encoding,设置打开文件的编码方式
  15. """
  1. # 返回一个操作文件的手柄,通过手柄操作文件指针进行文件读写
  2. handle = open(r"./other.py","w",encoding="utf-8")
  3.  
  4. # 删除文件
  5. os.remove(r"./other.py")
  6.  
  7. # 获取文件信息描述
  8. info = os.stat(r"./other.py")
  9. print(info)
  10.  
  11. # 重命名
  12. os.rename(r"./other.py", r"./test.py")
  1. # os 模块下有一个path,其下有一些操作文件的内容
  2.  
  3. # 获取指定文件的绝对路径 absolute。结果:/Users/guoyapeng/pyword/python_start
  4. abs_path = os.path.abspath("..")
  5. print(abs_path)
  6.  
  7. # 对路径进行拼接。想获取'day12_模块'的路径。join,第一个参数是:父级目录;第二个参数:要拼接的目录
  8. path = r"."
  9. sub_list = os.listdir(path) # 显示所有的子文件、子目录
  10. res_path = os.path.join(path,sub_list[2])
  11. print(res_path) # 相对路径结果:./time_text.py
  12.  
  13. # 获得指定路径的扩展名。结果是一个元组
  14. """
  15. 如果路径对应的是一个文件:
  16. 第一部分:是文件的路径
  17. 第二部分:文件的扩展名
  18. 如果路径对应的是一个文件夹:
  19. 第一部分:是文件夹的路径
  20. 第二部分:是空字符串
  21. """
  22. ex_name = os.path.splitext(res_path)
  23. print(ex_name) # 结果-目录:'../day12_模块', ''); 结果-文件: ('./time_text', '.py')
  24.  
  25. # 获取最后一级目录的名字
  26. base_name = os.path.basename(res_path)
  27. print(base_name) # 结果:time_text.py
  28.  
  29. # 获取除了最后一级的路径
  30. dir_name = os.path.dirname(res_path)
  31. print(dir_name) # 结果:.
  32.  
  33. # 获取指定文件的大小,单位是 字节
  34. len = os.path.getsize(base_name)
  35. print(len) # 结果:947
  36.  
  37. # 判断路径指向的文件是否存在
  38. res = os.path.exists(path)
  39. print(res) # 结果:True
  40.  
  41. # 判断路径指向的文件是否存在
  42. res = os.path.isfile(base_name)
  43. print(res) # 结果:True
  44.  
  45. # 判断路径指向的是否是一个文件夹
  46. res = os.path.isdir(base_name)
  47. print(res) # 结果 False
  48.  
  49. # 判断路径是否使用的是绝对路径
  50. res = os.path.isabs(dir_name)
  51. print(res) # 结果:False

获取指定目录下的所有文件

  • 普通获取
  1. import os
  2. """
  3. 获取指定目录下的所有文件
  4. 包含 子文件、次级子文件、次次级子文件 都得获取到
  5. 注意:
  6. 现在的方法中只能获取直接子文件
  7.  
  8. """
  9.  
  10. path = r".."
  11. # 获取直接子文件
  12. sub_list = os.listdir(path)
  13. print(sub_list)
  14. # 遍历列表
  15. for file_name in sub_list:
  16. # 需要判断file_name指定的是否是一个文件
  17. # 注意:如果设置路径的时候,只写的是路径的文件名字,表示这个文件与当前文件是平级的
  18. # 需要进行路径拼接。根据上一级目录 和 自己的名字拼接出全路径
  19. all_path = os.path.join(path,file_name)
  20. if os.path.isfile(all_path):
  21. print("---",all_path)
  22. elif os.path.isdir(all_path):
  23. # 获取子文件夹下的所有子目录
  24. sub_sub_list = os.listdir(all_path)
  25. # 遍历
  26. for sub_file_name in sub_sub_list:
  27. join_path = os.path.join(all_path,sub_file_name)
  28. if os.path.isfile(join_path):
  29. print(join_path)
  • 递归获取
  1. """
  2. 上面的代码重复:查找目录下子文件这个功能代码是重复的。可以把查找子文件的代码封装成一个函数
  3. """
  4. """
  5. 递归的出口: 不用再调用自己了。最后一级目录下全部是文件,或者是空目录
  6. """
  7. def get_all_file(path):
  8. # 获得路径下的所有直接子文件
  9. sub_list = os.listdir(path)
  10. # 遍历
  11. for file_name in sub_list:
  12. # 路径拼接
  13. join_path = os.path.join(path,file_name)
  14. # 判断这个目录指向的是否是一个文件
  15. if os.path.isfile(join_path):
  16. print(join_path)
  17. else:
  18. get_all_file(join_path)
  19.  
  20. get_all_file(r"..")
  1. """改进: 全面化"""
  2. def get_all_file(path):
  3. # 判断path指定的路径是否存在
  4. if os.path.exists(path):
  5. # 获得路径下的所有直接子文件
  6. sub_list = os.listdir(path)
  7. # 遍历
  8. for file_name in sub_list:
  9. # 路径拼接
  10. join_path = os.path.join(path,file_name)
  11. # 判断这个路径指向的是否是一个文件
  12. if os.path.isfile(join_path):
  13. print(join_path)
  14. else:
  15. get_all_file(join_path)
  16. else:
  17. print("路径不存在,请检查路径")
  18.  
  19. get_all_file(r"..")

删除指定目录下的所有文件

  • 普通删除
  1. # 假设目录下都是文件
  2. path = r"./a"
  3. # 获取子文件
  4. sub_list = os.listdir(path)
  5. print(sub_list) # 结果:['2.txt', '1.txt']
  6. for file_name in sub_list:
  7. # 拼接路径
  8. join_path = os.path.join(path,file_name)
  9. if os.path.isfile(join_path):
  10. # 移除文件
  11. os.remove(join_path)
  12. # 当遍历执行完毕,目录中的内容就被清空
  13. # 移除之后查看path指定的路径是否还有子文件
  14. print(os.listdir(path)) # 结果:[]
  15. os.rmdir(path)
  1. # 一个目录下既有文件,又有文件夹
  2. # a/1.txt;a/b/2.txt
  3. path = r"./a"
  4. # 获取它下面的子文件和子目录
  5. sub_list = os.listdir(path)
  6. print(sub_list) # 结果:['1.txt', 'b']
  7. # 遍历
  8. for file_name in sub_list:
  9. # 路径拼接
  10. join_path = os.path.join(path,file_name)
  11. if os.path.isfile(join_path):
  12. # 移除文件
  13. os.remove(join_path)
  14. elif os.path.isdir(join_path):
  15. # 获取b文件夹下的子文件和子目录
  16. b_sub_list = os.listdir(join_path)
  17. # 遍历
  18. for b_file_name in b_sub_list:
  19. # 拼接
  20. b_join_path = os.path.join(join_path,b_file_name)
  21. if os.path.isfile(b_join_path):
  22. os.remove(b_join_path)
  23.  
  24. # 出了遍历,删除b目录
  25. os.rmdir(join_path)
  26. # a中空了
  27. os.rmdir(path)
  • 递归删除
  1. """
  2. 上述代码可以看出:遍历文件夹删除文件夹中的文件的功能是重复的。可以把这个功能封装成函数
  3. """
  4.  
  5. def delete_dir(path)
  6. if os.path.exists(path):
  7. # 获得指定路径下的子文件和子目录
  8. sub_list = os.listdir(path)
  9. # 遍历
  10. for file_name in sub_list:
  11. # 拼接出file_name对应的真实路径
  12. join_path = os.path.join(path,file_name)
  13. # 判断这个路径指向的是否是一个文件
  14. if os.path.isfile(join_path):
  15. #移除文件
  16. os.remove(join_path)
  17. # 判断是否是目录,若是,递归遍历该目录
  18. elif os.path.isdir(join_path):
  19. delete_dir(join_path)
  20. # 当遍历走完,该目录就是一个空目录
  21. os.rmdir(path)
  22. else:
  23. print("路径不存在,请从新设置")

深度遍历广度遍历

  1. # 深度遍历
  2. """
  3. 需要借助 栈 的数据结构来完成。将要进行遍历的目录压栈。
  4. 栈的特点:先进后出。借助借助列表模拟栈
  5. """
  6.  
  7. # 广度遍历
  8. """
  9. 需要借助 队列 数据结构来完成。
  10. 队列特点:先进先出。collections模块下的dequeue队列类
  11. """
  1. """
  2. 题干: 获取a下的所有文件
  3. a
  4. 1.txt
  5. 2.txt
  6. b
  7. 3.txt
  8. c
  9. 4.txt
  10. b1
  11. 5.txt
  12. d
  13. 6.txt
  14. e
  15. 7.txt
  16. """
  • 深度遍历
  1. import os
  2. # 深度遍历。列表模拟,先进后出
  3.  
  4. def show_all_file(path):
  5. if os.path.exists(path):
  6. # 声明一个栈
  7. stack = []
  8. # 将即将遍历的主路径存放于栈中
  9. stack.append(path)
  10. # 遍历栈,---当栈中没有数据的时候,结束遍历
  11. while len(stack) != 0:
  12. # 取出栈中数据进行遍历
  13. data_path = stack.pop()
  14. # 获取该目录下的子文件和子目录
  15. sub_list = os.listdir(data_path)
  16. for file_name in sub_list:
  17. # 拼接真实的路径
  18. join_path = os.path.join(data_path,file_name)
  19. # 进行判断是否是文件
  20. if os.path.isfile(join_path):
  21. print(join_path)
  22. elif os.path.isdir(join_path):
  23. # 若是目录,将其压入栈中
  24. stack.append(join_path)
  25. else:
  26. print("路径不存在")
  27.  
  28. show_all_file(r"./a")
  • 广度遍历
  1. import os
  2. from collections import deque
  3. # 广度遍历。队列模拟,先进先出
  4.  
  5. def show_all_file(path):
  6. if os.path.exists(path):
  7. queue = deque() # 声明一空队列
  8. # 将即将遍历的路径存放于队列中
  9. queue.append(path)
  10. # 当队列中空了,没有数据了,停止遍历
  11. while len(queue) != 0:
  12. # 取出即将遍历的目录
  13. data_path = queue.popleft()
  14. # 获取目录下的子文件和子目录
  15. sub_list = os.listdir(data_path)
  16. # 遍历
  17. for file_name in sub_list:
  18. # 拼接
  19. join_path = os.path.join(data_path,file_name)
  20. # 进行判断
  21. if os.path.isfile(join_path):
  22. print(join_path)
  23. elif os.path.isdir(join_path):
  24. # 若是目录,压入到队列中
  25. queue.append(join_path)
  26. else:
  27. print("路径不存在")
  28.  
  29. show_all_file(r"./a")

python高级 之(四) --- 模块方法的更多相关文章

  1. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  2. python高级(四)—— 文本和字节序列(编码问题)

    本文主要内容 字符 字节 结构体和内存视图 字符和字节之间的转换——编解码器 BOM鬼符  标准化Unicode字符串 Unicode文本排序 python高级——目录 文中代码均放在github上: ...

  3. python的内置模块xml模块方法 xml解析 详解以及使用

    一.XML介绍 xml是实现不同语言或程序直接进行数据交换的协议,跟json差不多,单json使用起来更简单,不过现在还有很多传统公司的接口主要还是xml xml跟html都属于是标签语言 我们主要学 ...

  4. python正则表达式之re模块方法介绍

    python正则表达式之re模块其他方法 1:search(pattern,string,flags=0) 在一个字符串中查找匹配 2:findall(pattern,string,flags=0) ...

  5. Python高级编程-itertoos模块

    Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数. 首先我们看看itertools模块提供的几个“无限”迭代器, import itertools naturals = ...

  6. Python高级笔记(四) -- 多继承_方法解析顺序表MRO

    1. 多继承以及MRO顺序 1.1 单独调用父类的方法 # -*- encoding=utf-8 -*- class Parent(object): def __init__(self, name): ...

  7. Python单例模式的四种方法

    在这之前,先了解super()和__new__()方法 super()方法: 返回一个父类或兄弟类类型的代理对象,让你能够调用一些从继承过来的方法. 它有两个典型作用: a. 在单继承的类层次结构中, ...

  8. Python高级数据结构-Collections模块

    在Python数据类型方法精心整理,不必死记硬背,看看源码一切都有了之中,认识了python基本的数据类型和数据结构,现在认识一个高级的:Collections 这个模块对上面的数据结构做了封装,增加 ...

  9. python的内置模块re模块方法详解以及使用

    正则表达式 一.普通字符 .     通配符一个.只匹配一个字符 匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符 >>> import re ...

随机推荐

  1. 10-SQLServer中统计信息的使用

    一.总结 1.网址https://docs.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-stats-tr ...

  2. 【C#】图片处理(底片,黑白,锐化,柔化,浮雕,雾化)

    https://www.cnblogs.com/bomo/archive/2013/03/01/2939453.html --------------------------------------- ...

  3. http支持上传文件夹

    核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...

  4. HGOI 20191030am 题解

    Problem A 腿部挂件 给出$n$个数的序列$a_i$,支持$T$次操作. 每次操作形如$x , l , r$,计算$\max_{i = l}^{r} (a_i \oplus x)$的值. 对于 ...

  5. vue-cli3项目打包后,在自己搭的服务器上访问打包好的页面空白,处理方法

    我用vue开发的一个小项目,项目开发出雏形,想打包一下放测试,但是我想放测试前自己检查一下经过npm run build打包生成的项目,在本地服务器能不能正常跑,于是,经过网上大哥的帮忙,写了个简易的 ...

  6. jQuery文档操作之修改操作

    replaceWith() 语法: $(selector).replaceWith(content); 将所有匹配的元素替换成指定的string.js对象.jQuery对象. // 将所有的h5标题替 ...

  7. [CSP-S模拟测试]:循环依赖(拓扑)

    题目传送门(内部题148) 输入格式 每个测试点第一行为一个正整数$T$,表示该测试点内的数据组数. 接下来$T$组数据,每组数据第一行一个正整数$n$,表示有引用单元格进行计算的单元格数,接下来$n ...

  8. 有趣但是没有用的linux命令

    1,小火车 #yum install sl 2,黑客帝国,代码雨 # wget https://jaist.dl.sourceforge.net/project/cmatrix/cmatrix/1.2 ...

  9. bedtools 用法大全

    原文:https://cloud.tencent.com/developer/article/1078324 前言: bedtools等工具号称是可以代替普通的生物信息学数据处理工程师的!我这里用一个 ...

  10. LeetCode 142. 环形链表 II(Linker List Cycle II)

    题目描述 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 说明:不允许修改给定的链表. 进阶: 你是否可以不用额外空间解决此题? 解题思路 分为三步: 首先判断是否存在 ...