题目
假设我们有如下数据:
A B C D E C F G C
先使以 G 来分割这个 list ,如果是上面的数据,则得到如下两个 list :
1. A B C D E C F G
2. C
这个题目其实就是 Java 中 String 类中的 split 方法类似的功能。我倒是想出了一个类似递归的方式来解决这个问题,步骤如下所示:
- 使用 list 的 contain 方法,判断 G 是否在 list 里面。
- 如果 G 在数组里面,则使用 indexOf 找出 G 所在的位置 i。
- 使用 sublist 将 0 到 i 的元素分离处理放到另外的 list 里面。
- 将 i + 1 到 list.size 的元素作为下次函数执行的对象。
- 知道 list 里面没有 G 为止。
那位看官说了,不是题目是说是去掉里面的环吗?我看到子集合 1 里面从 C D E C
从 C 又回到了 C,
这样就是我所说的环,对于这个环,我应该怎样呢?我的要求是做 C D E C
-> C
这样的变换。
我先来谈谈我的想法。我可以从 list 的最后一个或者第一个开始,我这个从最后一个开始元素(k)开始,将其他的元素看作是另外一个 list ,我在这个 list 里面查找 k ,如果能查找到 k ,则说明“环”是存在的。如果环存在,那我们应该怎么弄呢?还能咋弄,删除它。从 k 在 list 所在的位置(不包含 k 这个位置),一直删除到 k 在大的 list 的位置。推广一下,如果没有在小的 list 里面找到 k ,那就要将 k 往前移动,来到 k+1 。如下图所示:
代码
整体的代码如下所示,
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
String ss = null ;
CartPath cp = new CartPath();
List<String> p = new ArrayList<>();
p.add("A");
p.add("B");
p.add("C");
p.add("D");
p.add("E");
p.add("D");
p.add("C");
p.add("F");
p.add("G");
p.add("F");
p.add("G");
cp.setPath(p);
List<List<String>> lists = splitCart(cp);
for(List<String> e : lists){
System.out.println(e);
}
System.out.println("-------");
generateCartPath(lists).forEach( x -> {
System.out.println(x.getPath());
});
}
public static List<List<String>> splitCart(CartPath cp ){
List<String> cartPath = cp.getPath() ;
List<List<String>> rs = new ArrayList<>();
int g = -1 ;
while(cartPath.contains("G")){
g = cartPath.indexOf("G");
rs.add(deleteCircle(cartPath.subList(0, g+1)));
// subList 方法其实是在原来的 list 上面做的删除操作,所以在上面的操作中,cartPath 的大小已经变小了。所以 g 的大小需要再取一次。
g = cartPath.indexOf("G");
cartPath = cartPath.subList(g+1 , cartPath.size());
}
return rs ;
}
public static List<String> deleteCircle( List<String> path){
int i = path.size() - 1 ;
int ii = 0 ;
while( i >= 0 ){
if(path.subList(0 , i).contains(path.get(i))){
ii = path.subList(0 , i).indexOf(path.get(i));
eraseCircle(path.subList(0,i),ii,i);
i = ii ;
}else {
i--;
}
}
return path;
}
public static void eraseCircle(List<String> path , int start , int end ){
path.subList(start,end).clear();
}
}
其中,SplitCart 这个函数实现了 split 的逻辑。
deleteCircle 函数是删除环的功能。这个我使用 sublist() 函数和 clear 函数,在需要处理连续数据的时候可以使用这个两个函数,比较好用。