Flatten Nested Arrays(展平嵌套數組)

這個題目是在一個公司現場面談的時候的一個題目。雖然對這種找工作上來就做題目的現象比較反感。

但是大環境如此,也只能被蹂躪了。

中文描述

題目要求比較簡單:[1,2,[3],[[4]],5,6] -> [1,2,3,4,5,6]

就是數組中嵌套數組,考察一個數組[1,2,[3],[[4]],5,6]。 你怎麼能夠輸出 1,2,3,4,5,6(並不要求按照順序輸出)。

這裏是一個嵌套數組,你需要將這個數組中的值全部取出來。

思路和點評

不清楚其他語言中這個數據結構怎麼存儲,我假設的是在 Java 中存儲的對象。

可以採用隊列的方式來實現,例如,在 Java 中存儲了整數,1, 2, 對象,[3] 爲一個數組對象。

你可以先遍歷一次 List,將所有的 List 的對象都壓入隊列中,然後進行出隊。

在出隊時候,判斷對象是否爲整數對象,如果是整數對象,就輸出,如果不是整數對象,然後將數組對象繼續進行遍歷,然後壓入隊列,然後再出隊。

在這裏討論的問題比較多,還有 [[[2]5]] 這種多層嵌套的問題。

經過網站上的考古,這裏有 2 個方法可以更快的實現。1 是遞歸的方法,2 是 利用 Java 8 的 Stream 特性。

在寫測試代碼之前,你需要明白下數據結構的定義,要不然你沒有辦法測試。在 Java 中你可以定義爲對象數組,如下:

Object[] array = { 12new Object[] { 34new Object[] { 5new Object[] { new Object[] { 6 } } }, 7 }, 8910 };

然後可以利用遞歸,在對對象數組進行遍歷的時候,如果你遇到了對象,那麼你需要再次調用你的方法,對對象中的內容進行遍歷,如果這個時候已經沒有對象了,可以返回第二層遍歷的結果,並且插入到上層 List 列表中。

如果你使用的 Java 8 的 Stream,你需要對 Stream 的使用和方法比較瞭解纔可以。這裏也涉及到了遞歸,只是寫法有點不同罷了。

還有一個更加簡單粗暴的方法,當然我不認爲這個方法是出題人希望考察的目標,在 Java 中你可以將數組直接轉換成 String 字符串進行輸出,比如說上面的對象隊列,你可以轉換爲: [1, 2, [3, 4, [5, [[6]]], 7], 8, 9, 10]  字符串進行輸出,然後使用 Java 的 Split 函數,進行按照逗號拆分後,然後將多餘 [ 和 ] 符號去掉,然後再將內容重新放回 List。 這個有點簡單粗暴,但是也一樣能夠達到目的。

源代碼

源代碼和有關代碼的更新請訪問 GitHub:

https://github.com/cwiki-us/codebank-algorithm/blob/master/src/test/java/com/ossez/codebank/interview/tests/PillPackTest.java

測試類請參考:

https://github.com/cwiki-us/codebank-algorithm/blob/master/src/test/java/com/ossez/codebank/interview/tests/PillPackTest.java

代碼思路請參考:



package com.ossez.codebank.interview.tests;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * PillPack
 * 
 * <pre>
 * https://www.cwiki.us/display/ITCLASSIFICATION/Flatten+Nested+Arrays
 * </pre>
 * 
 * @author YuCheng
 *
 */
public class PillPackTest {

	private final static Logger logger = LoggerFactory.getLogger(PillPackTest.class);

	List<Integer> returnList = new ArrayList<Integer>();

	/**
	 * https://www.cwiki.us/display/ITCLASSIFICATION/Flatten+Nested+Arrays
	 * 
	 * FlattenNestedArrays
	 */
	@Test
	public void testFlattenNestedArrays() {
		logger.debug("Test FlattenNestedArrays");

		Object[] array = { 1, 2, new Object[] { 3, 4, new Object[] { 5, new Object[] { new Object[] { 6 } } }, 7 }, 8, 9, 10 };
		logger.debug("LOOP: {} - > {}", Arrays.deepToString(array), Arrays.toString(loopFlatten(array)));

		logger.debug("Java 8: {} - > {}", Arrays.deepToString(array), Arrays.toString(java8Flatten(array).toArray()));

	}

	/**
	 * Loop And Recursive
	 * 
	 * @param inputArray
	 * @return
	 * @throws IllegalArgumentException
	 */
	private static Integer[] loopFlatten(Object[] inputArray) throws IllegalArgumentException {
		// NULL CHECK
		if (inputArray == null)
			return null;

		List<Integer> flatList = new ArrayList<Integer>();

		for (Object element : inputArray) {
			if (element instanceof Integer) {
				flatList.add((Integer) element);
			} else if (element instanceof Object[]) {
				// Recursive
				flatList.addAll(Arrays.asList(loopFlatten((Object[]) element)));
			} else {
				throw new IllegalArgumentException("Input must be an array of Integers or nested arrays of Integers");
			}
		}
		return flatList.toArray(new Integer[flatList.size()]);
	}

	/**
	 * Java 8 Stream to Flatten array.
	 * 
	 * @param array
	 * @return
	 */
	private static Stream<Object> java8Flatten(Object[] array) {
		// int[] flatInt = java8Flatten(array).mapToInt(Integer.class::cast).toArray();
		return Arrays.stream(array).flatMap(o -> o instanceof Object[] ? java8Flatten((Object[]) o) : Stream.of(o));

	}

}


測試結果

上面程序的測試結果如下:

2018/12/27 13:39:22 DEBUG [com.ossez.codebank.interview.tests.PillPackTest] - Test FlattenNestedArrays
2018/12/27 13:39:22 DEBUG [com.ossez.codebank.interview.tests.PillPackTest] - LOOP: [1, 2, [3, 4, [5, [[6]]], 7], 8, 9, 10] - > [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2018/12/27 13:39:22 DEBUG [com.ossez.codebank.interview.tests.PillPackTest] - Java 8: [1, 2, [3, 4, [5, [[6]]], 7], 8, 9, 10] - > [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章