[leetcode] 339. Nested List Weight Sum

题目链接: https://leetcode.com/problems/nested-list-weight-sum/

 

Given a nested list of integers, return the sum of all integers in the list weighted by their depth.

Each element is either an integer, or a list -- whose elements may also be integers or other lists.

Example 1:
Given the list [[1,1],2,[1,1]], return 10. (four 1's at depth 2, one 2 at depth 1)

Example 2:
Given the list [1,[4,[6]]], return 27. (one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4*2 + 6*3 = 27)

 fb: 原题的weight是1,2,3,...
改成了1,2,6,24,...这样子

Time Complexity: O(n). n 是指全部叶子的数目加上dfs走过层数的总数. [[[[[5]]]],[[3]], 1], 3个叶子, dfs一共走了6层. 所以用了 3 + 6 = 9 的时间. 

Space: O(D). D 是recursive call用的stack的最大数目, 即是最深的层数, 上面例子最深走过4层, 这里D = 4.

  Depth and unpacked nested list are being passed to the next recursive call. Anytime, an integer is encountered, a value is evaluated and incremented to the stack's sum. The sum is then returned to the caller once the for loop ends. Since this is a tree, there is no need to keep track of visited nodes like general graph traversal.

/**
 * // This is the interface that allows for creating nested lists.
 * // You should not implement it, or speculate about its implementation
 * public interface NestedInteger {
 *
 *     // @return true if this NestedInteger holds a single integer, rather than a nested list.
 *     public boolean isInteger();
 *
 *     // @return the single integer that this NestedInteger holds, if it holds a single integer
 *     // Return null if this NestedInteger holds a nested list
 *     public Integer getInteger();
 *
 *     // @return the nested list that this NestedInteger holds, if it holds a nested list
 *     // Return null if this NestedInteger holds a single integer
 *     public List<NestedInteger> getList();
 * }
 */
public class Solution {
    public int depthSum(List<NestedInteger> nestedList) {
        return depthSum(nestedList, 1);
    }
    
    public int depthSum(List<NestedInteger> nestedList, int weight) {
        int sum = 0;
        for (NestedInteger each : nestedList) {
            if (each.isInteger()) 
                sum += each.getInteger() * weight;
            else sum += depthSum(each.getList(), weight+1);
        }
        return sum;
    }
}

  

iterative

This can also be categorized as Level-order tree traversal algorithm. The algorithm will travel level by level and increment the running sum when integer is encountered. Queue is used as data structure due to the nature of BFS where it needs to process data sequentially for each level.

public int depthSum(List<NestedInteger> nestedList) {
    if(nestedList == null){
        return 0;
    }
    
    int sum = 0;
    int level = 1;
    
    Queue<NestedInteger> queue = new LinkedList<NestedInteger>(nestedList);
    while(queue.size() > 0){
        int size = queue.size();
        
        for(int i = 0; i < size; i++){
            NestedInteger ni = queue.poll();
            
            if(ni.isInteger()){
                sum += ni.getInteger() * level;
            }else{
                queue.addAll(ni.getList());
            }
        }
        
        level++;
    }
    
    return sum;
}

  

接口的实现:

/**
 * This is the interface that represents nested lists. You should not implement
 * it, or speculate about its implementation.
 */
interface NestedInteger {
	/**
	 * @return true if this NestedInteger holds a single integer, rather than a
	 *         nested list
	 */
	boolean isInteger();

	/**
	 * @return the single integer that this NestedInteger holds, if it holds a
	 *         single integer Return null if this NestedInteger holds a nested
	 *         list
	 */
	Integer getInteger();

	/**
	 * @return the nested list that this NestedInteger holds, if it holds a
	 *         nested list Return null if this NestedInteger holds a single
	 *         integer
	 */
	List<NestedInteger> getList();
}

class MyNestedIneteger implements NestedInteger {

	private Integer theSingleInteger;
	private List<NestedInteger> theList;

	public MyNestedIneteger(Integer theSingleInteger, List<NestedInteger> theList) {
		this.theSingleInteger = theSingleInteger;
		this.theList = theList;
	}

	@Override
	public boolean isInteger() {
		return null == theList && null != theSingleInteger;
	}

	@Override
	public Integer getInteger() {
		return theSingleInteger;
	}

	@Override
	public List<NestedInteger> getList() {
		return theList;
	}

	@Override
	public String toString() {

		StringBuilder string = new StringBuilder();

		string.append("{");
		if (null != theSingleInteger) {
			string.append(theSingleInteger);
		}
		if (null != theList) {
			for (NestedInteger current : theList) {
				string.append(", " + current.toString());
			}
		}
		string.append("}");
		return string.toString();
	}

}

public class NestedIntegerSum {

	/**
	 * Given a nested list of integers, returns the sum of all integers in the
	 * list weighted by their depth For example, given the list {{1,1},2,{1,1}}
	 * the function should return 10 (four 1's at depth 2, one 2 at depth 1)
	 * Given the list {1,{4,{6
the function should return 27 (one 1 at depth 
* 1, one 4 at depth 2, and one 6 at depth 3) 
*/ 
public static int depthSum(List<NestedInteger> input) { 
    if (null == input) { 
        return 0; 
    } else { 
        int sum = 0; 
        for (NestedInteger current : input) { 
            sum += depthSumNestedInteger(current, 1); 
        } 
        return sum; 
    } 

} 

private static int depthSumNestedInteger(NestedInteger current, int level) { 
    System.out.println("current: " + current + " level: " + level); 
    if (null == current) { 
        return 0; 
    } else { 
        if (current.isInteger()) { 
            return current.getInteger() * level; 
        } else { 
            int tempSum = 0; 
            if (current.getInteger() != null) { 
                tempSum = current.getInteger() * level; 
            } 
            for (NestedInteger nestedCurrent : current.getList()) { 
                tempSum += depthSumNestedInteger(nestedCurrent, level + 1); 
            } 
        return tempSum; 
        } 
    } 
} 

public static void main(String[] args) { 

List<NestedInteger> list1 = new ArrayList<>(); 
List<NestedInteger> list2 = new ArrayList<>(); 

NestedInteger nestedInteger1 = new MyNestedIneteger(1, list1); 
NestedInteger nestedInteger2 = new MyNestedIneteger(4, list2); 
NestedInteger nestedInteger3 = new MyNestedIneteger(6, null); 

list1.add(nestedInteger2); 
list2.add(nestedInteger3); 

List<NestedInteger> input = new ArrayList<>(); 
input.add(nestedInteger1); 

System.out.println(input); 
System.out.println(depthSum(input)); 
} 

}    

  

  

posted @ 2017-12-02 03:10  apanda009  阅读(1681)  评论(0编辑  收藏  举报