博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
普林斯顿算法课Part2第四周作业_Boggle
阅读量:4695 次
发布时间:2019-06-09

本文共 3291 字,大约阅读时间需要 10 分钟。

作业地址:http://coursera.cs.princeton.edu/algs4/assignments/boggle.html

作业难点:

1、如何保证求解速度,满分要求是求解速度 >= 0.5 * 参考速度,约在5000次/5s。

  1)最直观的算法思想:要明确查找单词即为对一个游戏板(board)上的一个顶点向8个方向进行深度优先遍历,在遍历过程中查找单词是否在词典中,将在词典中的单词记录保存下来。为顺利找出所有满足条件的单词,可以使用广度、深度优先遍历该顶点。重复遍历完所有顶点即可找出在词典中的所有单词。

  2)根据算法思想构建数据结构:游戏板-board[][]一个二维数组,构建词典使用教材提及的TST(三叉单词查找树)或者Trie(单词查找树),保存已找出的单词(因为按题目要求重复单词只保留一个)使用HashSet,遍历方法采用dfs(深度优先搜索)方法。

  3)根据dfs原理构建算法求解,使用marked[][]标记已访问的顶点,使用TST构建词典,求解速度约在2500次/5s,需要优化。

  4)为避免回溯过程中重复查找单词树,为TST新增一个hasPrefix(String key)函数(查找单词树中是否包含key前缀),返回TST的Node类型:root——未查找到,非root——查找到。因为返回的是Node,所以每次只需查找Node以后的枝叶即可,key也即board[i][j]的字母即可。此时,求解速度约在3500次/5s,需要优化。

  5)弃用TST,改用Trie构建词典,修改hasPrefix()函数为getNext(String key)函数,此时求解速度上次到6500次/5s,可以满分,离参考值还有一段距离。

  6)因为查找的过程中存在重复单词,所以在开始的时候使用HashSet来保存找到的单词,存在查找重复单词并将其重复插入的情况。为避免对重复单词进行多次处理,设置处理过的单词的val值为-1,并记录该节点的位置,将其保存下来,在处理的最后对节点的val进行恢复。没有了重复单词,也就不需要HashSet来保存查找到的单词,使用简单的链表来保存即可,保存单词的速度更快。此时求解速度可以上升到10000次/5s。

容易扣分点:

同作业难点。

部分代码:

1、数据结构:

private Trie dict;    private String[][] gameStr;    private Bag
words; // found words private Bag
nodes; // nodes of found words private static class Trie { private static int R = 26; // Radix, English alphabet private static final int OFFSET = 'A'; public Node root; class Node { int val; Node[] next = new Node[R]; } }

 

2、getAllValidWords(BoggleBoard board):

public Iterable
getAllValidWords(BoggleBoard board) { words = new Bag
(); nodes = new Bag
(); int col = board.cols(), row = board.rows(); boolean[][] marked = new boolean[row][col]; gameStr = new String[row][col]; for (int i = 0; i < row; i++) for (int j = 0; j < col; j++) gameStr[i][j] = representQ(i, j, board); for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { Trie.Node pNode = dict.getNext(dict.root, gameStr[i][j]); if (pNode != null) dfs(board, marked, i, j, pNode, gameStr[i][j]); } } for (Trie.Node n : nodes) n.val = 1; return words; } private void dfs(BoggleBoard board, boolean[][] marked, int x, int y, Trie.Node pNode, String preStr) { marked[x][y] = true; String curStr; int xNeighbor, yNeighbor; Trie.Node queryNode; if (pNode.val == 1 && preStr.length() > 2) { words.add(preStr); nodes.add(pNode); pNode.val = -1; } for (int i = 0; i < XDELTA.length; i++) { xNeighbor = x + XDELTA[i]; yNeighbor = y + YDELTA[i]; if (validPos(xNeighbor, yNeighbor, board) && !marked[xNeighbor][yNeighbor]) { queryNode = dict.getNext(pNode, gameStr[xNeighbor][yNeighbor]); if (queryNode != null) { curStr = preStr + gameStr[xNeighbor][yNeighbor]; dfs(board, marked, xNeighbor, yNeighbor, queryNode, curStr); } } } marked[x][y] = false; }
View Code

 

转载于:https://www.cnblogs.com/notTao/p/6389629.html

你可能感兴趣的文章
iOS 中的加密方式
查看>>
pdftk
查看>>
OS_EVENT 信号量
查看>>
学习ThreadLocal
查看>>
在 Visual Studio 调试器中指定符号 (.pdb) 和源文件
查看>>
直接量
查看>>
leetcode 115. 不同的子序列(Distinct Subsequences)
查看>>
三元表达式
查看>>
Go初接触之libjpeg-turbo
查看>>
python--生成器协程运算
查看>>
php中文字符串截取乱码问题解决
查看>>
INFT 3030 Concurrent Programming
查看>>
小心了,这个设置会导致你的vm重启时被强制重装系统!
查看>>
邮票面值设计 (动态规划+DFS)
查看>>
解决INSTALL_FAILED_MISSING_SHARED_LIBRARY (转载)
查看>>
Linux内核高端内存
查看>>
HTML列表
查看>>
JAVA插入数据到MySql少了8小时
查看>>
【Objective-C学习记录】01-基础概念
查看>>
诗词十四首
查看>>