标签:哈密顿 int ans 平方和 回溯 new searched 回路
找出最小的 n>1,使得存在一个存储了 [1, n] 的某个排列的循环数组,数组中任意相邻两项之和都是完全平方数。
题解:构造一个无向图,循环数组中的每一个元素作为图中的点,图中的每一个点的值与它的邻接点的值相加为平方和,利用回溯法找图中的哈密顿回路(一次经过图中的所有点(只经过一次)并能回到出发点的回路)。我们逐渐增大图的大小,找图中的哈密顿回路,第一个能找到哈密顿回路的图大小即为最小的n
class Solution {
public int getAns(){
for(int i=1;i<Integer.MAX_VALUE;i++){
map test=new map(i);
test.dfs(1,i);
if(test.ans.size()!=0) {
System.out.println(test.ans.toString());
return i;
}
}
return -1;
}
public static void main(String[] args) {
System.out.println(new Solution().getAns());
}
}
class map {
boolean found = false;
boolean[] searched;
Deque<Integer> ans = new LinkedList<>();
Map<Integer, ArrayList<Integer>> edge = new HashMap<>();
Set<Integer> nums = new HashSet<>();
public map(int n) {
searched = new boolean[n];
int max = (int) Math.sqrt((double)n*(n-1)/2);
for (int i = 2; i < max; i++) {
nums.add(i * i);
}
//哈希存储图中每个点的邻接点
for (int i = 1; i <= n; i++) {
ArrayList<Integer> To = new ArrayList<>();
for (int x : nums) {
if (x - i != i&&x-i>0&&x-i<=n) {
To.add(x - i);
}
}
edge.put(i, To);
}
}
//求图中的哈密顿回路
public void dfs(int pos, int n) {
if (found)
return;
if (ans.size() == n) {
//判断终点与起点能否向连接
if (!ans.isEmpty()&&nums.contains(pos + ans.peekFirst())) {
found = true;
}
}
for (int x : edge.get(pos)) {
if (!searched[x - 1]) {
ans.addLast(x);
searched[x - 1] = true;
dfs(x, n);
if(!found) {
ans.pollLast();
searched[x - 1] = false;
}
}
}
}
}
运行结果:
[3, 6, 30, 19, 17, 32, 4, 21, 28, 8, 1, 15, 10, 26, 23, 2, 14, 22, 27, 9, 16, 20, 29, 7, 18, 31, 5, 11, 25, 24, 12, 13]
n=32
标签:哈密顿,int,ans,平方和,回溯,new,searched,回路 来源: https://blog.csdn.net/CY2333333/article/details/111673991
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。