Jerry's Blog

Recording what I learned everyday

View on GitHub


8 November 2019

LeetCode(60) -- 45, 49, 103

by Jerry Zhang

P45. Jump Game II (Medium)

一个数组,起始点在第一个数字上。每个数字代表从该位置最多可以跳多少步。问至少需要多少步能跳可末尾?

我的思路

动态规划,每一步都有A[i]种选择,选择哪一个取决于选择这个后,从那个位置最少多少步才能跳到最后。但是实现的时候还是需要从最左边往右推进,而不是重复地计算。每个位置,都要记录下来最少多少步就可以跳到该位置。

我的代码

public class M_45_JumpGameII {
    public int jump(int[] nums) {
        int[] memo = new int[nums.length];
        memo[0] = 0;
        for (int i = 1; i < memo.length; i++) {
            memo[i] = Integer.MAX_VALUE;
        }
        for (int i = 0; i < nums.length - 1; i++) {
            int j = i + 1;
            while (j <= i + nums[i]) {
                memo[j] = Math.min(memo[i] + 1, memo[j]);
                j++;
            }
        }
        return memo[nums.length - 1];
    }

    public static void main(String[] args) {
        int jump = new M_45_JumpGameII().jump(new int[]{2, 3, 1, 1, 4});
        System.out.println("jump = " + jump);

    }
}

18%

最优解

class Solution {
    public int jump(int[] nums) {
        if(nums.length < 2)
            return 0;
        int n = nums.length;
        int ladder = nums[0];
        int stairs = nums[0];
        int jump = 1;
        for (int i = 1; i < n - 1; i++) {
            if((i + nums[i]) > ladder) {
                ladder = i + nums[i];
            }
            stairs--;
            if(stairs == 0){
                jump++;
                stairs = ladder - i;
            }
        }
        return jump;
    }
}

讨论区

public int jump(int[] A) {
	int jumps = 0, curEnd = 0, curFarthest = 0;
	for (int i = 0; i < A.length - 1; i++) {
		curFarthest = Math.max(curFarthest, i + A[i]);
		if (i == curEnd) {
			jumps++;
			curEnd = curFarthest;
		}
	}
	return jumps;
}

用这个,简单明了。

P49. Group Anagrams (Medium)

把所有用相同字母组成的单词分成一组。

Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

我的思路

用hashmap存所有的字母组合。把相同的字母组合归为一类。

我的代码

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        HashMap<Statistic, List<String>> map = new HashMap<>();
        for (String s : strs) {
            int[] table = new int[26];
            for (char c : s.toCharArray()) {
                table[c - 'a']++;
            }
            Statistic statistic = new Statistic(table);
            List<String> list = map.getOrDefault(statistic, new ArrayList<>());
            list.add(s);
            map.put(statistic, list);
        }
        return new ArrayList<>(map.values());
    }

    class Statistic{
        int[] table;

        public Statistic(int[] table) {
            this.table = table;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Statistic statistic = (Statistic) o;
            return Arrays.equals(table, statistic.table);
        }

        @Override
        public int hashCode() {
            return Arrays.hashCode(table);
        }
    }
}

97%

最优解

class Solution {
    // idea here is to
    public List<List<String>> groupAnagrams1(String[] strs) {
        if(strs == null || strs.length == 0)
            return new ArrayList<>();

        Map<String, List<String>> map = new HashMap<>();

        for(String s: strs){
            char[] charArray = s.toCharArray();
            Arrays.sort(charArray);
            String str = new String(charArray);
            map.putIfAbsent(str, new ArrayList<>());
            map.get(str).add(s);
        }
        return new ArrayList<>(map.values());
    }

    public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> result = new ArrayList();
        Map<String, List<String>> codeMap = new HashMap();
        for (String current : strs) {
            String charRepresentation = getCharRepresentation(current);
            if (codeMap.containsKey(charRepresentation)) {
                codeMap.get(charRepresentation).add(current);
            } else {
                List<String> codeValues = new ArrayList();
                codeValues.add(current);
                codeMap.put(charRepresentation, codeValues);
                result.add(codeValues);
            }
        }

        return result;
    }

    private String getCharRepresentation(String value) {
        char[] freq = new char[26];
        for (char c : value.toCharArray()) {
            freq[c - 'a']++;
        }

        return new String(freq);
    }
}

P103. Binary Tree Zigzag Level Order Traversal (Medium)

二叉树,之字形遍历。第一行从左向右,第二行从右向左,第三行从左向右……

我的思路

层级遍历时用一个Queue, 但因为要换方向,所以每次放入下一层节点以前,先把所有节点放进stack中。弹出的时候,再根据是从左向右或者从右向左,决定先放左子节点还是先放右子节点。

我的代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> ans = new ArrayList<>();
        if (root == null) {
            return ans;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        boolean leftToRight = true;
        Stack<TreeNode> stack = new Stack<>();
        while (!queue.isEmpty()) {
            int size = queue.size();
            List<Integer> level = new ArrayList<>();
            for (int i = 0; i < size; i++) {
                TreeNode node = queue.remove();
                level.add(node.val);
                stack.push(node);
            }
            while (!stack.isEmpty()) {
                TreeNode pop = stack.pop();
                if (leftToRight) {
                    if (pop.right != null) {
                        queue.add(pop.right);
                    }
                    if (pop.left != null) {
                        queue.add(pop.left);
                    }
                } else {
                    if (pop.left != null) {
                        queue.add(pop.left);
                    }
                    if (pop.right != null) {
                        queue.add(pop.right);
                    }
                }
            }
            leftToRight = !leftToRight;
            ans.add(level);
        }
        return ans;
    }
}

98%

最优解

class Solution {
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if(root==null) return res;
        Queue<TreeNode> q = new LinkedList<>();
        q.add(root);
        boolean isOdd = true;
        while(!q.isEmpty()) {
            LinkedList<Integer> tmp = new LinkedList<>();
            int size = q.size();
            for(int i = 0; i < size; ++i) {
                TreeNode n = q.poll();
                if(isOdd) {
                    tmp.add(n.val);
                } else {
                    tmp.addFirst(n.val);
                }
                if(n.left != null) q.add(n.left);
                if(n.right != null) q.add(n.right);
            }
            res.add(tmp);
            isOdd = !isOdd;
        }
        return res;
    }
}

用linkedList活用,可以加在前面或者加在后面。

tags: LeetCode