算法:去环行动

题目

假设我们有如下数据:

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 方法类似的功能。我倒是想出了一个类似递归的方式来解决这个问题,步骤如下所示:

  1. 使用 list 的 contain 方法,判断 G 是否在 list 里面。
  2. 如果 G 在数组里面,则使用 indexOf 找出 G 所在的位置 i。
  3. 使用 sublist 将 0 到 i 的元素分离处理放到另外的 list 里面。
  4. 将 i + 1 到 list.size 的元素作为下次函数执行的对象。
  5. 知道 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 函数,在需要处理连续数据的时候可以使用这个两个函数,比较好用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值