实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
# @author:leacoder
# @des: 二分查找 , x 的平方根
class Solution:
def mySqrt(self, x: int) -> int:
if x == 1 or x == 0:
return x
left,right,res = 0,x,0
while left <= right:
mid = int((left + right)/2)
if mid * mid > x:
right = mid - 1
elif mid *mid < x:
left = mid + 1
res = mid
else:
return int(mid)
return int(res)
# @author:leacoder
# @des: 牛顿迭代 , x 的平方根
# 参看 https://www.cnblogs.com/qlky/p/7735145.html
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 1:
return x
r = x
while r * r > x:
r = int((r + x / r) /2)
return r
class Solution:
def mySqrt(self, x: int) -> int:
if x <= 1:
return x
r = x
r = 0x5f3759df - (r >> 1)
while r * r > x:
r = int((r + x / r) /2)
return int(r)
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
开发系统: Ubuntu 16.0.4 LTS
开发IDE: Visual Studio Code 版本: 1.32.3
Python版本: Python3
依赖库: pygame
链接:https://pan.baidu.com/s/1USkqvL2dLU3Q9XplVaGQJg
提取码:zoyc
https://github.com/lichangke/Python3_Project/tree/master/data_visual
matplotlib:https://matplotlib.org/
sudo apt-get install python3-matplotlib
pygal:http://www.pygal.org/en/stable/
pip install –user pygal
pip install pygal_maps_world 额外需安装
matplotlib 简单使用,访问相关第三方库中链接了解更多
# | 文件名 | 内容 |
---|---|---|
- | mpl_squares.py | 绘制折线图 |
- | random_walk.py | Python来生成随机漫步数据 |
- | rw_visual.py | 循环生成随机漫步数据并生成显示图像,需random_walk.py |
- | scatter_squares.py | 绘制散点图 |
'''
@File : mpl_squares.py
@Time : 2019/04/06 16:45:51
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 绘制折线图
'''
# here put the import lib
# 导入了模块pyplot
import matplotlib.pyplot as plt
input_values = [1, 2, 3, 4, 5] # X 轴数据
squares = [1, 4, 9, 16, 25] # Y 轴数据
'''
plot(*args[, scalex, scaley, data])
绘制 x y 坐标组成的线
'''
plt.plot(input_values, squares, linewidth=5)
# 设置图表标题, 并给坐标轴加上标签
plt.title( "Square Numbers", fontsize = 24 )
plt.xlabel( "Value", fontsize = 14 )
plt.ylabel( "Square of Value", fontsize = 14 )
# 设置刻度标记的大小
plt.tick_params( axis = 'both', labelsize = 14 , colors = 'r' ) # axis 将参数应用于哪个轴
plt.show()
'''
打开matplotlib查看器, 并显示绘制的图形
'''
'''
@File : random_walk.py
@Time : 2019/04/06 17:39:26
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : Python来生成随机漫步数据
'''
# here put the import lib
from random import choice
class RandomWalk():
"""一个生成随机漫步数据的类"""
def __init__(self, num_points=5000):
"""初始化随机漫步的属性"""
self.num_points = num_points
# 所有随机漫步都始于(0, 0)
self.x_values = [0]
self.y_values = [0]
def fill_walk(self):
# 不断漫步, 直到列表达到指定的长度
while len(self.x_values) < self.num_points:
# 决定前进方向以及沿这个方向前进的距离
x_direction = choice([1, -1])
x_distance = choice([0, 1, 2, 3, 4])
x_step = x_direction * x_distance
y_direction = choice([1, -1])
y_distance = choice([0, 1, 2, 3, 4])
y_step = y_direction * y_distance
# 拒绝原地踏步
if x_step == 0 and y_step == 0:
continue
# 计算下一个点的x和y值
next_x = self.x_values[-1] + x_step
next_y = self.y_values[-1] + y_step
self.x_values.append(next_x)
self.y_values.append(next_y)
'''
@File : rw_visual.py
@Time : 2019/04/07 00:56:52
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 循环生成随机漫步数据并显示
'''
# here put the import lib
import matplotlib.pyplot as plt
from random_walk import RandomWalk
# 只要程序处于活动状态, 就不断地模拟随机漫步
while True:
rw = RandomWalk(50000)
rw.fill_walk()
'''
figure([num, figsize, dpi, facecolor, ...])
Create a new figure.
figsize : (float, float), optional, default: None
width, height in inches. If not provided, defaults to rcParams["figure.figsize"] = [6.4, 4.8].
dpi : integer, optional, default: None
resolution of the figure. If not provided, defaults to rcParams["figure.dpi"] = 100.
'''
# 设置绘图窗口的尺寸
plt.figure(figsize=(10, 6),dpi=128)
point_numbers = list(range(rw.num_points))
plt.scatter(rw.x_values, rw.y_values, s=1, c=point_numbers,
cmap=plt.cm.Blues, edgecolor='none')
# 突出起点和终点
plt.scatter(0, 0, c='green', edgecolors='none', s=100)
plt.scatter(rw.x_values[-1], rw.y_values[-1],
c='red', edgecolors='none', s=100)
'''
The Axes class The Axes contains most of the figure elements: Axis, Tick, Line2D, Text, Polygon, etc., and sets the coordinate system.
'''
# 隐藏坐标轴
plt.axes().get_xaxis().set_visible(False) # Return the XAxis instance.
plt.axes().get_yaxis().set_visible(False) # Return the YAxis instance.
plt.show()
keep_running = input("Make another walk? (y/n): ")
if keep_running == 'n':
break
'''
@File : scatter_squares.py
@Time : 2019/04/06 17:08:01
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 绘制散点图
'''
# here put the import lib
import matplotlib.pyplot as plt
'''
scatter(x, y[, s, c, marker, cmap, norm, ...])
绘制x y 坐标的散点图,并设置不同的 标记 大小 或 颜色等。
'''
x_values = [1, 2, 3, 4, 5]
y_values = [1, 4, 9, 16, 25]
color = ['r', 'g', 'b']
# s 标记大小 以磅为单位**2 c 颜色,序列或颜色序列
plt.scatter(x_values, y_values, s=100, c=color)
# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)
plt.show()
# 循环绘制1000个点
x_values = list(range(1, 1001))
y_values = [x**2 for x in x_values]
'''
c : color, sequence, or sequence of color, optional
A single color format string.
A sequence of color specifications of length n.
A sequence of n numbers to be mapped to colors using cmap and norm. #使用cmap和norm映射到颜色的n个数字序列
A 2-D array in which the rows are RGB or RGBA.
cmap : Colormap, optional, default: None # cmap 告诉pyplot 使用哪个颜色映射
edgecolors : color or sequence of color, optional, default: 'face' # 边框颜色
'''
plt.scatter(x_values, y_values, s=40, c=y_values, cmap=plt.cm.Blues, edgecolor='none')
# 设置图表标题并给坐标轴加上标签
plt.title("Square Numbers", fontsize=24)
plt.xlabel("Value", fontsize=14)
plt.ylabel("Square of Value", fontsize=14)
# 设置刻度标记的大小
plt.tick_params(axis='both', which='major', labelsize=14)
'''
axis(*v, **kwargs)
获取或设置某些轴属性的便捷方法
xmin, xmax, ymin, ymax = axis()
xmin, xmax, ymin, ymax = axis(xmin, xmax, ymin, ymax)
xmin, xmax, ymin, ymax = axis(option)
xmin, xmax, ymin, ymax = axis(**kwargs)
'''
# 设置每个坐标轴的取值范围
plt.axis([0, 1100, 0, 1100000])
plt.show()
pygal 简单使用,访问相关第三方库中链接了解更多
# | 文件名 | 内容 |
---|---|---|
- | die.py | 骰子类 |
- | die_visual.py | 模拟掷骰子并柱状图显示点数出现次数,需die.py |
- | die_visual.svg | 生成的svg,可用浏览器打开 |
'''
@File : die.py
@Time : 2019/04/06 21:53:11
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 骰子类
'''
# here put the import lib
from random import randint
class Die():
"""表示一个骰子的类"""
def __init__(self, num_sides=6):
"""骰子默认为6面"""
self.num_sides = num_sides
def roll(self):
""""返回一个位于1和骰子面数之间的随机值"""
return randint(1, self.num_sides)
'''
def randint(a, b)
Return random integer in range [a, b], including both end points.
'''
'''
@File : die_visual.py
@Time : 2019/04/06 21:56:06
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 模拟掷骰子并柱状图显示点数出现次数
'''
# here put the import lib
from die import Die
import pygal
# 创建两个D6
die_1 = Die(8)
die_2 = Die(8)
# 掷几次骰子, 并将结果存储在一个列表中
results = []
for roll_num in range(50000):
result = die_1.roll()+die_2.roll()
results.append(result)
# 分析结果
frequencies = []
max_result = die_1.num_sides + die_2.num_sides
for value in range(2, max_result+1):
frequency = results.count(value)
frequencies.append(frequency)
# 对结果进行可视化
hist = pygal.Bar() # Basic simple bar graph:
hist.title = "Results of rolling a D8 and a D8 50,000 times."
x_labels = set()
for i in range(1,die_1.num_sides+1):
for j in range(1, die_2.num_sides+1):
x_label = i + j
x_labels.add(x_label)
print(x_labels)
hist.x_labels = list(x_labels)
hist.x_title = "Result"
hist.y_title = "Frequency of Result"
# 使用add() 将一系列值添加到图表中(向它传递要给添加的值指定的标签, 还有一个列表, 其中包含将出现在图表中的值) 。
hist.add('D8 + D8', frequencies)
hist.render_to_file('die_visual.svg') # 最后, 我们将这个图表渲染为一个SVG文件
对CSV文件格式的数据处理,通过matplotlib绘制CSV文件中温度数据的折线图
|#| 文件名| 内容 | | -|——| ———–| | -|highs_lows.py|处理CSV文件数据,matplotlib绘制最高温度最低温度折线图| | -|其他.csv| csv格式的温度数据|
'''
@File : highs_lows.py
@Time : 2019/04/06 22:32:59
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 处理CSV文件数据,matplotlib绘制最高温度最低温度折线图
'''
# here put the import lib
# c sv 模块包含在Python标准库中
import csv
from matplotlib import pyplot as plt
# 模块datetime 处理日期
from datetime import datetime
# 从文件中获取日期、 最高气温和最低气温
filename = 'death_valley_2014.csv'
with open(filename) as f:
# 创建一个与该文件相关联的阅读器(reader ) 对象
reader = csv.reader(f)
# 模块csv 包含函数next() , 调用它并将阅读器对象传递给它时, 它将返回文件中的下一行。 在前面的代码中, 我们只调用了next() 一次, 因此得到的是文件的第一行, 其中包含文件头
header_row = next(reader)
dates, highs, lows = [], [], []
for row in reader: # 遍历文件中余下的各行
try: # 错误检查
current_date = datetime.strptime(row[0], "%Y-%m-%d") # '2014-7-1
high = int(row[1])
low = int(row[3])
except ValueError:
print(current_date, 'missing data')
else:
dates.append(current_date)
highs.append(high)
lows.append(low)
# 根据数据绘制图形
fig = plt.figure(dpi=123, figsize=(10, 6))
'''
plot(*args[, scalex, scaley, data])
Plot y versus x as lines and/or markers.
alpha: float Set the alpha value used for blending - not supported on all backends.
'''
plt.plot(dates, highs, c='red', alpha=0.5) # 绘制最高温度
plt.plot(dates, lows, c='blue', alpha=0.5) # 绘制最低温度
'''
fill_between(x, y1[, y2, where, ...])
Fill the area between two horizontal curves.
'''
plt.fill_between(dates, highs, lows, facecolor='blue', alpha=0.1)
# 设置图形的格式
plt.title("Daily high temperatures - 2014", fontsize=24)
plt.xlabel('', fontsize=16)
'''
autofmt_xdate(self, bottom=0.2, rotation=30, ha='right', which=None)
Date ticklabels often overlap, so it is useful to rotate them and right align them.
bottom : scalar
The bottom of the subplots for subplots_adjust().
rotation : angle in degrees
The rotation of the xtick labels.
ha : string
The horizontal alignment of the xticklabels.
which : {None, 'major', 'minor', 'both'}
Selects which ticklabels to rotate. Default is None which works the same as major.
'''
fig.autofmt_xdate()
title = "Daily high and low temperatures - 2014\nDeath Valley, CA"
plt.title(title, fontsize=24)
'''
tick_params([axis])
Change the appearance of ticks, tick labels, and gridlines. 更改刻度,刻度标签和网格线的外观
axis : {'x', 'y', 'both'}, optional
Which axis to apply the parameters to.
which : {'major', 'minor', 'both'}
Default is 'major'; apply arguments to which ticks.
'''
plt.tick_params(axis='both', which='major', labelsize=16)
plt.show()
对json文件格式的数据处理,通过pygal绘制世界人口地图
# | 文件名 | 内容 |
---|---|---|
- | country_codes.py | 处理国家识别码 |
- | population_data.json | json文件格式的数据 |
- | world_population.py | 对json文件格式的数据处理,通过pygal绘制世界人口地图,需country_codes.py |
- | world_population.svg | 绘制生成的世界人口地图 |
'''
@File : countries.py
@Time : 2019/04/06 23:42:39
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 处理国家识别码
'''
# here put the import lib
# from pygal.i18n import COUNTRIES 模块已被遗弃 但是现在可以在 pygal_maps_world 插件中找到它 pip3 install pygal_maps_world
from pygal.maps.world import COUNTRIES
def get_country_code(country_name):
"""根据指定的国家, 返回Pygal使用的两个字母的国别码"""
for country_code in sorted(COUNTRIES.keys()):
for code, name in COUNTRIES.items():
if name == country_name:
return code
# 如果没有找到指定的国家, 就返回None
return None
'''
@File : world_population.py
@Time : 2019/04/06 23:36:41
@Author : leacoder
@Version : 1.0
@Contact : leacock1991@gmail.com
@License :
@Desc : 对json文件格式的数据处理,通过pygal绘制世界人口地图
'''
# here put the import lib
''' 导入画地图的模块 '''
import pygal.maps.world
''' 解析json文件 '''
import json
'''世界地图的样式'''
import pygal
from pygal.style import RotateStyle # 十六进制颜色
from pygal.style import LightColorizedStyle # 加亮地图的颜色
from country_codes import get_country_code
# 将数据加载到一个列表中
filename = 'population_data.json'
with open(filename) as f:
pop_data = json.load(f)
# 创建一个包含人口数量的字典
cc_populations = {}
for pop_dict in pop_data:
if pop_dict['Year'] == '2010':
country_name = pop_dict['Country Name']
# population = int(pop_dict['Value']) # '1127437398.85751' Python不能直接将包含小数点的字符串'1127437398.85751' 转换为整数
# 先将字符串转换为浮点数, 再将浮点数转换为整数:
population = int(float(pop_dict['Value']))
code = get_country_code(country_name)
if code:
cc_populations[code] = population
else:
print('ERROR - ' + country_name)
# 根据人口数量将所有的国家分成三组
cc_pops_1, cc_pops_2, cc_pops_3 = {}, {}, {}
for cc, pop in cc_populations.items():
if pop < 10000000:
cc_pops_1[cc] = pop
elif pop < 1000000000:
cc_pops_2[cc] = pop
else:
cc_pops_3[cc] = pop
# 看看每组分别包含多少个国家
print(len(cc_pops_1), len(cc_pops_2), len(cc_pops_3))
'''
class pygal.style.RotateStyle(color, step=10, max_=None, base_style=None, **kwargs)
Create a style by rotating the given color
'''
wm_style = RotateStyle('#336699', base_style=LightColorizedStyle) # 十六进制颜色码
# wm = pygal.Worldmap() # 已不可用 使用.maps.world.World()替代
wm = pygal.maps.world.World() # 初始化一个地图对象
wm.style = wm_style # 设置地图的风格
wm.title = 'World Population in 2010, by Country'
#wm.add('2010', cc_populations)
wm.add('0-10m', cc_pops_1)
wm.add('10m-1bn', cc_pops_2)
wm.add('>1bn', cc_pops_3)
wm.render_to_file('world_population.svg')
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
原文:http://blog.thefirehoseproject.com/posts/learn-to-code-and-be-self-reliant/ 原作者:Ken Mazaika
当你学习编码时,会有一个一切开始变化的时刻。在 Firehose,我们把这个时刻称为编码的拐点。跨过这个阶段,你作为开发者的编程方式将大不相同。
当你开始学习编码时,你目前有很多还不知道的信息。这些信息被称为特定领域的知识(domain-specific knowledge)。
对于初学者来说,最重要的技能是注重细节: 在阅读文档或教程等材料时,密切关注细节非常重要。即使是最小的拼写错误也会导致错误消息或者错误。查看错误消息一开始会令人不舒服,但却是学习过程中至关重要的一步。在这个阶段,处理错误消息和问题会教你在安全编程环境中编程的最重要的技能之一:面向细节。
调试错误信息非常重要: 事实上,错误信息只是编程的一部分:缺乏经验和经验丰富的开发者都会遇到它们。唯一的区别是,处理错误消息的经验越多,花在尝试修复错误消息上的时间就越少。 学会如何阅读错误消息并快速提取出问题的相关细节 应该从你解决的每条错误消息中学习,不要只是修复错误并完成它,要理解到底是哪里出错了。通过学习每个错误,下次出现同样的错误时,你将能够更快地修复错误。
编程的晦涩的小秘密是… 你永远不会知道解决所有问题所需要知道的一切,编程是需要终身学习的。
在以下情况下,你就将准备好进入下一阶段: 你已将看到了足够多的错误消息,它们不会再让你感到惊讶。 你变得擅长使用 Google 搜索解决方法。 你能够引用你在应用程序其他部分编写的代码并遵循其中的模式,而不总是寻找逐步的说明。
拐点阶段是学习编码最令人沮丧的阶段之一,但在很多方面,它是唯一重要的阶段。在这个阶段,你逐步停止使用教程,并开始解决没有人为你提供解决方法的问题。
在拐点阶段,你的编码速度可能比之前的阶段慢 10 到 20 倍: 你可能会开始质疑你自己并想知道你是否真的有能力成为程序员。在这个阶段,不安和怀疑的感觉很常见。尽管事实上你会觉得你正在以更慢的速度学习和完成事情,但实际上,你正在实现最重要的事情。 程序性的知识是一种能力,在整个过程教会你自己你不知道的东西。当你需要实现一个新功能时,你应该使用哪个类型的 Google 搜索?在这个阶段,当遇到你想要完成的许多事情时,你会觉得自己“处在黑暗当中”。学习如何自己找到光亮是至关重要的,因为你永远不会知道所有要知道的事情,所以你需要能够自学如何解决手头的问题。
在你的余生中,每一天都超出你的极限: 一些软件工程师一旦找到自己的立足点就会留在舒适区内。这些类型的程序员被称为维护程序员——不是你应该努力成为的那种。相反,你应该努力每天超出你的极限。你应该寻找超出当前技能的问题,而不是试图将编码项目拉入你的舒适区。这是建立和扩展你的技能的唯一的方法。
在教程阶段,从浏览结构化教材中抽出点时间,在这个过程中给自己一些有挑战的问题。 对于每一课,尝试做一些超出你所遵循的教程范围的事情。 尝试可能少地使用教程。 专注于那些基本的东西并重复使用。
越过拐点可能具有挑战性。这里有一些指导可以帮你完成它: 明白这是一个艰难的过程,从容一些。你正在学习很多,但在这个阶段,你正在学习一种全新的技巧,可以自己解决新事物的技巧。 如果你在自信心中挣扎,你的感受是完全正常的。继续学习。如果你继续挣扎,试着和最近通过拐点的人交谈。他们将能够站在你的角度,并让你相信你所遇到的只是暂时的。持续地工作,但不要过度劳累。
在这个阶段获得信心的最好的方法是通过解决你遇到的问题。
拐点过程的最后阶段是接受。接受软件开发是一个持续学习的过程。接受你成功学习一切的感觉只意味着你应该开始考虑解决更复杂的问题。
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
下面是我整理的关于 Python3的相关知识点,欢迎大家来一起交流学习。 建议基础知识学习后对python的标准库以及常用第三方库进行了解熟悉
如需要xmind 格式的,可以去我的GitHub下载: https://github.com/lichangke/Mind-Mapping/tree/master/Python3
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
编写一个程序,通过已填充的空格来解决数独问题。
一个数独的解法需遵循如下规则:
数字 1-9
在每一行只能出现一次。
数字 1-9
在每一列只能出现一次。
数字 1-9
在每一个以粗实线分隔的 3x3
宫内只能出现一次。
空白格用 '.'
表示。
一个数独。
答案被标成红色。
Note:
给定的数独序列只包含数字 1-9
和字符 '.'
。
你可以假设给定的数独只有唯一解。
给定数独永远是 9x9
形式的。
/*
* @author:leacoder
* @des: DFS 无优化版 解数独
*/
class Solution {
public void solveSudoku(char[][] board) {
if(board == null || board.length == 0) return;
solve_DFS(board);
}
public boolean solve_DFS(char[][] board){
for ( int y = 0; y < board.length; y++){
for( int x = 0; x < board[y].length; x++){ //遍历数独每个格子
if( board[y][x] == '.'){ // 判断是否为空
for( char c = '1'; c <= '9'; c++){ // 遍历 1 - 9 数字 是否可行 ,ASCII 中 字符 1 - 9连续
if( isValid(board, y, x, c) ){ // 是否可填 c
board[y][x] = c; // 填入 然后 DFS 判断 是否正确
if(solve_DFS(board)){
return true; // ok 成功 正确
}
else{ //失败 不正确
board[y][x] = '.'; //重新标记为空白 不填
}
}
}
return false; // 1 - 9 没有数能填入 失败
}
}
}
return true;
}
public boolean isValid(char[][] board,int row,int col, char c){ // 可填校验
for(int i = 0; i < 9; i++){
if(board[i][col] !='.' && board[i][col] == c){ // 列检测
return false; // 检查 每一行 中 col 位是否合法 不能已存在 c
}
if(board[row][i] !='.' && board[row][i] == c) {// 行检测
return false; // 检查 每一列 中 row 位是否合法 不能已存在 c
}
if(board[3 * (row/3) + i/3][3 * (col/3) + i%3] != '.' && board[3 * (row/3) + i/3][3 * (col/3) + i%3] == c){
return false; // 小 3x3 宫内检测
}
}
return true; // 均检测通过
}
}
ToDo
GitHub链接: https://github.com/lichangke/LeetCode
个人Blog: https://lichangke.github.io/
欢迎大家来一起交流学习
n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
上图为 8 皇后问题的一种解法。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。
每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q'
和 '.'
分别代表了皇后和空位。
示例:
输入: 4
输出:
[
[".Q..", // 解法 1
"...Q",
"Q...",
"..Q."],
["..Q.", // 解法 2
"Q...",
"...Q",
".Q.."]
]
解释: 4 皇后问题存在两个不同的解法。
# @author:leacoder
# @des: DFS 深度优先 N皇后
class Solution:
def solveNQueens(self, n: int) -> List[List[str]]:
if n < 1 : return [] #
self.result = []
shu = [] # 竖方向是否被攻击
pie = [] # 撇方向是否被攻击 x y 坐标之和固定 x + y
na = [] # 捺方向是否被攻击 x y 坐标之差固定 x - y
self.DFS(n,shu,pie,na)
return self.generate(n)
def DFS(self,n,shu,pie,na): #深度优先搜索
p = len(shu) # 从 1 -> n
if p == n :
self.result.append(shu) #每层有且只能放一个
return None
for q in range(n): # 看成 x 每层枚举可能的 x
if q not in shu and p - q not in na and p + q not in pie: #这一层存在可能位置,向下层搜索
self.DFS(n,shu+[q],pie+[p+q],na+[p-q]) #深度优先搜索 将被攻击的 坐标记录下来
def generate(self,n):
board=[]
for res in self.result: #
for count in res:
board.append( "." * count + "Q" + "." * (n - count -1)) #将所有存放在一个列表中
finalresult = []
for i in range(0,len(board),n): # 按每n组成一个新列表,最后生成所需形式
finalresult.append(list(board[i:i+n]))
return finalresult