函数main接受一个字符串数组作为争论,并将打印一行输出。输出将按顺序输入,使得每个字符串的第一个字母与前一个字符串的最后一个字母相同,但最后一个字符串的最后一个字母与第一个字符串的第一个字母相同。如果不存在包含所有字符串的订单,则代码将不打印解决方案
输入和输出示例:
输入:松鼠的眼睛klondlike lasik
输出:squirrel lasik klondlike eyes
输入:为什么我们不能跳舞
输出:无解决方案
输入:apple tampa elephant
输出:apple elephant tampa
我编写了大部分代码但是我的排序方法并不适用于每个测试用例,因为它的编写方式,是否有人能够提供帮助?
<coordinator-app name="${jobName}" frequency="${coord:days(1)}" start="2000-01-01T12:00Z" end="3000-01-01T12:00Z" timezone="UTC" xmlns="uri:oozie:coordinator:0.2">
<controls>
<timeout>-1</timeout>
<concurrency>1</concurrency>
<execution>LAST_ONLY</execution>
</controls>
<action>
<workflow>
<app-path>${myAppPath}</app-path>
</workflow>
</action>
</coordinator-app>
答案 0 :(得分:3)
您可以尝试使用递归方法。主要思想是检查每个单词是否可能在链中。
private String[] findRing(String... words) {
for (int i = 0; i < words.length; i++) {
String word = words[i];
String[] result = findRingForHeadAndTail(word, dropElementWithIndex(i, words));
if ((result.length == words.length - 1) &&
(word.charAt(0) == result[result.length - 1].charAt(result[result.length - 1].length() - 1))) { //word started from last letter in tail
return concatHeadAndTail(word, result);
}
}
return new String[]{"NO SOLUTION"};
}
private String[] findRingForHeadAndTail(
String head, //first word
String... tail //other words
) {
if (tail.length == 0) { // if we don't have other words then just return empty array
return new String[0];
}
if (tail.length == 1) { // if we have just one word in tail
if (tail[0].charAt(0) == head.charAt(head.length() - 1)) { //and this word begins with last letter in head
return tail; //return this tail
} else {
return new String[0]; //otherwise return empty array
}
}
for (int i = 0; i < tail.length; i++) { // for every word
String word = tail[i];
if (word.charAt(0) == head.charAt(head.length() - 1)) { // if this word begins with last letter in head
String[] result = findRingForHeadAndTail( //recursive call for
word, //picked word
dropElementWithIndex(i, tail) // all other words in tail
);
if (result.length == tail.length - 1) { // if recursive call returns the same amount of words as we passed there as tail
return concatHeadAndTail(word, result); //return array {head, tail}
}
}
}
return new String[0];
}
//returns array as {head, tail}
private String[] concatHeadAndTail(String head, String... tail) {
return Stream.concat(Stream.of(head), Stream.of(tail)).collect(Collectors.toList()).toArray(new String[tail.length + 1]);
}
//removes element with index i from words
private String[] dropElementWithIndex(int i, String... words) {
List<String> result = new ArrayList<>();
for (int j = 0; j < words.length; j++) {
if (j != i) {
result.add(words[j]);
}
}
return result.toArray(new String[words.length - 1]);
}
输出:
@Test
public void findRing() {
System.out.println(Arrays.toString(findRing("squirrel", "eyes", "klondlike", "lasik")));
System.out.println(Arrays.toString(findRing("why", "cant", "we", "dance")));
System.out.println(Arrays.toString(findRing("apple", "tampa", "elephant")));
System.out.println(Arrays.toString(findRing("apple", "elephant", "tampa")));
System.out.println(Arrays.toString(findRing("elephant", "apple", "tampa")));
System.out.println(Arrays.toString(findRing("alfa", "alfa", "beta")));
System.out.println(Arrays.toString(findRing("alfa", "alfa")));
System.out.println(Arrays.toString(findRing("alfa", "alfa", "bravo")));
}
是:
[squirrel, lasik, klondlike, eyes]
[NO SOLUTION]
[apple, elephant, tampa]
[apple, elephant, tampa]
[elephant, tampa, apple]
[NO SOLUTION]
[alfa, alfa]
[NO SOLUTION]
UPDATE 以前的解决方案在更糟糕的情况下具有复杂度O(n!)。 FDesu提出了不同的解决方案,它基于Adjacency matrix的一个属性。
如果A是有向图或无向图G的邻接矩阵,那么矩阵An(即A的n个副本的矩阵乘积)具有一个有趣的解释:元素(i,j)给出的数量(有向或无向的)从顶点i到顶点j的长度为n的步长。
该算法具有复杂度O(n ^ 4),但对内存也有其他要求,因为我们应该存储所有可能的路径。
private void findRingWithMatrix(String... words) {
System.out.println("For example: " + Arrays.toString(words));
boolean[][] initialAdjacencyMatrix = new boolean[words.length][words.length];
List<String[]> paths = new ArrayList<>();
//Build initial adjacency matrix
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words.length; j++) {
initialAdjacencyMatrix[i][j] = (i != j) && (couldBeInChain(words[i], words[j]));
//if node is reachable
if (initialAdjacencyMatrix[i][j]) {
//put this path to possible paths
paths.add(new String[]{words[i], words[j]});
}
}
}
//create temporary copy of matrix to multiply
boolean[][] tempAdjacencyMatrix = initialAdjacencyMatrix.clone();
//We should multiply matrix N-1 times, because first step in graph we've already done on previous step
for (int n = 1; n < words.length; n++) {
boolean[][] bufferAdjacencyMatrix = new boolean[words.length][words.length];
List<String[]> newPathes = new ArrayList<>();
//multiply matrices (next step and initial). In result we get [true] in node which is reachable from first node in N steps
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words.length; j++) {
for (int k = 0; k < words.length; k++) {
bufferAdjacencyMatrix[i][j] |= (tempAdjacencyMatrix[i][k] && initialAdjacencyMatrix[k][j]);
}
//if node reachable
if (bufferAdjacencyMatrix[i][j]) {
//create new path and put it list of possible paths
for (String[] path : paths) {
if (couldBeInChain(path[path.length - 1], words[j])) {
String[] newPath = new String[path.length + 1];
System.arraycopy(path, 0, newPath, 0, path.length);
newPath[newPath.length - 1] = words[j];
newPathes.add(newPath);
}
}
}
}
}
paths = removeDuplicates(newPathes);
System.out.println("Step #" + n);
printMatrix(bufferAdjacencyMatrix);
tempAdjacencyMatrix = bufferAdjacencyMatrix;
}
boolean isRing = true;
//Ring could be just if after (N-1) multiplications we have [true] in main diagonal.
//In other words, can reach every node in N steps.
for (int i = 0; i < words.length; i++) {
isRing = tempAdjacencyMatrix[i][i];
if (!isRing) {
break;
}
}
if (!isRing) {
System.out.println("NO SOLUTION");
return;
} else {
System.out.println("Found solutions:");
for (String[] path : paths) {
//we are interested just in solutions when first node is equals to last one
if (path[0].equals(path[path.length - 1])) {
String[] toPrint = new String[path.length - 1];
System.arraycopy(path, 0, toPrint, 0, toPrint.length);
System.out.println(Arrays.deepToString(toPrint));
}
}
}
System.out.println("==============================");
}
private boolean couldBeInChain(String first, String second) {
return first.charAt(first.length() - 1) == second.charAt(0);
}
private List<String[]> removeDuplicates(List<String[]> newPathes) {
return newPathes
.stream()
.map(Arrays::asList)
.collect(Collectors.collectingAndThen(Collectors.toSet(), new Function<Set<List<String>>, List<String[]>>() {
@Override
public List<String[]> apply(Set<List<String>> lists) {
List<String[]> result = new ArrayList<>();
for (List<String> list : lists) {
result.add(list.toArray(new String[list.size()]));
}
return result;
}
}));
}
private void printMatrix(boolean[][] matrix) {
System.out.println("-------------------------------");
for (boolean[] row : matrix) {
System.out.println(Arrays.toString(row));
}
System.out.println("-------------------------------");
}
答案 1 :(得分:1)
class T
{
public static void main(String[] args)
{
int k=1;
Scanner sc=new Scanner(System.in);
String str=sc.nextLine();
String[] word=str.split(" ");
StringBuilder str1=new StringBuilder(word[0]);
while(str1.toString().length()!=str.length())
{
for(int j,i=1;i<word.length;i++)
{
for(j=1;j<word.length;j++)
{
if((str1.toString()).endsWith(Character.toString(word[j].charAt(0))))
{
str1.append(" "+word[j]);
}
}
}
break;
}
for(int i=0;i<word.length;i++)
{
if((str1.toString()).indexOf(word[i])<0)
{
str1.insert(0,word[i]+" ");
k=k+1;
}
}
if(k==word.length)
System.out.println(str);
else
System.out.println("NO SOLUTION");
}
}