OA總結

Rotate Stringjava

  • 題目:
  • 思路:
class Solution {
    public boolean rotateString(String A, String B) {
        if (A == null || B == null || A.length() != B.length()) {
            return false;
        }
        
        String C = B + B;
        return C.indexOf(A) == -1 ? false : true;
    }
}
複製代碼

Closest Two Sum max average sum subetree 兩種版本: 1.二叉樹 2.多個子節點 merge two Sorted List 一排數據中心,每一個數據中心連接有cost, 求將全部數據中心鏈接起來而且cost最小的方式 Leetcode 819 Leetcode 973 K Closest Points to Originnode

  • 問題: 給出一個二維數組表示一些點的座標和一個值K,求出距離原點(0,0)最近的K個點,並放在二維數組中返回
  • 思路: 維護一個size 爲K的最大堆,用來更新距離前k小的點

PriorityQueue<Integer> pq = new PriorityQueue(k, new Comparator<Integer>(public int compare(int a, int b) {return b - a;}))) compare是聲明的方法git

PriorityQueue<Point> pq = new PriorityQueue<Point> (k, new Comparator<Point> () {
    @Override
    public int compare(Point a, Point b) {
        return (int) (getDistance(a, origin) - getDistance(b, origin));
    }
});

// 實現最大堆的代碼須要記憶
class Solution {
    public int[][] kClosest(int[][] points, int K) {
        Queue<int[]> queue=new PriorityQueue<>((a, b) -> (a[0]*a[0]+a[1]*a[1])-(b[0]*b[0]+b[1]*b[1]));
        int[][] res=new int[K][2];
        int index=0;
        for(int[] arr:points) {
            queue.add(arr);
        }
        while(index<K) {
            res[index]=queue.poll();
            index++;
        }
        return res;
    }
}
複製代碼

LintCode High Five數組

public class Solution {
    /** * @param results a list of <student_id, score> * @return find the average of 5 highest scores for each person * Map<Integer, Double> (student_id, average_score) */
    public Map<Integer, Double> highFive(Record[] results) {
        Map<Integer, Double> answer = new HashMap<Integer, Double>();
        Map<Integer, PriorityQueue<Integer>> hash = new HashMap<Integer, PriorityQueue<Integer>>();

        for (Record r : results) {
            if (!hash.containsKey(r.id)){
                hash.put(r.id, new PriorityQueue<Integer>());
            }
            PriorityQueue<Integer> pq=hash.get(r.id);
            if (pq.size() < 5) {
                pq.add(r.score);
            } else {
                if (pq.peek() < r.score){
                    pq.poll();
                    pq.add(r.score);
                }
            }
        }

        for (Map.Entry<Integer, PriorityQueue<Integer>> entry : hash.entrySet()) {
            int id = entry.getKey();
            PriorityQueue<Integer> scores = entry.getValue();
            double average = 0;
            for (int i = 0; i < 5; ++i)
                average += scores.poll();
            average /= 5.0;
            answer.put(id, average);
        }
        return answer;
    }
}
複製代碼

K - 1 Substringide

Valid Parenthesisoop

[LintCode] 597 Subtree with Maximum Averagethis

  • 題目: 給出一棵二叉樹,找出其中平均值最大的子樹節點
  • 思路: 新寫一個ResultType類來將保存node,size子樹節點個數,sum(子樹值的總和)
  • 變形: 給出多叉樹,或者只能返回非葉節點
public class Solution {
    /** * @param root: the root of binary tree * @return: the root of the maximum average of subtree */
     
    private class Result {
        private int sum;
        private int size;
        private TreeNode node;
        public Result(int sum, int size, TreeNode node) {
            this.sum = sum;
            this.size = size;
            this.node = node;
        }
    }
    
    private Result currMax = null;
    
    public TreeNode findSubtree2(TreeNode root) {
        // write your code here
        if (root == null) {
            return null;
        }
        helper(root);
        return currMax.node;
    }
    
    private Result helper(TreeNode node) {
        if (node == null) {
            return new Result(0,0,null);
        }
        Result left = helper(node.left);
        Result right = helper(node.right);
        Result res = new Result(
            left.sum + right.sum + node.val,
            left.size + right.size + 1,
            node);
        if (currMax == null || res.sum * currMax.size > res.size * currMax.sum) {
            currMax = res;
        }
        return res;
    }
}
複製代碼
public class Solution {
    class Result {
        CategoryNode node;
        int sum;
        int size;
        public Result(CategoryNode node, int sum, int size) {
            this.node = node;
            this.sum = sum;
            this.size = size;
        }
    }
    
    private Result currMax = null;
    public CategoryNode getMostPupularNode(CategoryNode rootCategory) {
        if (rootCategory == null) {
            return null;
        }
        Result rootRes = helper(rootCategory);
        return res.node;
    }
    
    public Result helper(CategoryNode root) {
        if (root == null) {
            return new Result(null, 0, 0);
        }
        ArrayList<Result> results = new ArrayList<Result>();
        for (CategoryNode n : root.subCategoryNode) {
            results.add(helper(n));
        }
        int childSum = 0;
        int childSize = 0;
        for (Result r : results) {
            childSum += r.sum;
            childSize += r.size;
        }
        
        Result c = new Result(root)
    }
}

複製代碼

819. Most Common Wordspa

  • 題目: 給出一個長的String段落和一個詞彙黑名單,找出不在禁用詞當中的頻率最高的詞
  • 思路: 先切割段落,而後統計詞頻,找出不在黑名單中的單詞 統計詞頻是用HashMap. 切割段落的時候要同時用到空格和逗號兩個分隔符?
// 直接一句話搞定 兩種狀況 在map中的+1 和 不在map中的直接新建爲1
    for (String word : words) {
        map.put(word, map.getOrDefault(word, 0) + 1);
    }

class Solution {
    public String mostCommonWord(String paragraph, String[] banned) {
        if (paragraph == null || paragraph.length() == 0) {
            return "";
        }
        HashMap<String, Integer> map = new HashMap<>();
        // 使用窮舉法進行段落分割 `+`加號在這裏表示出現次數爲屢次
        String[] words = paragraph.toLowerCase().split("[ ?!;,.']+");
        
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        for (String word : banned) {
            if (map.containsKey(word)) {
                map.remove(word);
            }
        }
        String res = null;
        for (String key : map.keySet()) {
            if (res == null || map.get(key) > map.get(res)) {
                res = key;
                System.out.println(key + "" + map.get(key));
            }
        }
        return res;
    }
}
複製代碼

雙指針類

全部的雙指針類型的題目都是要維持指針區間,必定會有多個循環條件,已經指針的更新條件的變化,注意指針移動變化以後的變量與不變量 兩個指針更新方式 能夠經過while loop或者 for loop指針

  • 同向雙指針
  • Longest Substring with At Most Two Distinct Characters
    • 題目: 找出只有兩個distinct字符的最長子串
    • 思路: 用count[]數組來記錄出現次數, 用distinctCount變量記錄出現的distinct字符數
    class Solution {
    public int lengthOfLongestSubstringTwoDistinct(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }   
        int maxSize = 0;
        int size = s.length();
        int[] count = new int[128];
        int distinctCount = 0;
        int j = 0;
        for (int i = 0; i < size; i++) {
            while (j < size) {
                if (distinctCount == 2 && count[s.charAt(j)] == 0) {
                    break;
                }
                if (count[s.charAt(j)] == 0) {
                    distinctCount++;
                }
                count[s.charAt(j++)]++;
            }
            maxSize = Math.max(maxSize, j - i);
            count[s.charAt(i)]--;
            if (count[s.charAt(i)] == 0) {
                distinctCount--;
            }
        }
        
        return maxSize;
    }
    複製代碼

} ```code

  • Longest Substring with At Most K Distinct Characters
  • 相向雙指針

LintCode 533 [Two Sum Closest]

  • 對撞型雙指針
  • 問題: 找到不大於k的最接近的一組數字
  • 思路: 先排序
public int twoSumClosest(int[] nums, int target) {
    if (nums == null || nums.length < 2) {
        return -1;
    }
    
    Arrays.sort(nums);
    int left = 0;
    int right = nums.length - 1;
    int diff = Integer.MAX_VALUE;
    
    while (left < right) {
        if (nums[left] + nums[right] < target) {
            diff = Math.min(diff, target - nums[left] - nums[right]);
            left++;
        }
        else {
            diff = Math.min(diff, nums[left] + nums[right] - target);
            right--;
        }
    }
    
    return diff;
}
複製代碼

Shortest path in a Binary Maze

  • https://en.wikipedia.org/wiki/Lee_algorithm Lee Algorithm:
  1. initialize
  2. wave expansion: repeat mark all unlabeled neighbors of points marked with i with i + 1
  3. go to target point -> repeat go to next node that has a lower mark than the current node
  4. clear marks

Reorder 字符的字典序比較 dictionary order alphabetical order "ah1".compareTo("ahb") 比較的就是兩個字符的ASCII差值,若是小於零說明第一個字符串小於第二個字符串

64. Minimum Path Sum

  • 題目: 給出一個m * n的方格,找出一條從左上到右下和最小的路徑, 只能夠向下或向右移動
  • 思路: 局部最小和全局最小之間的關係?全局最小也是局部最小
public class Solution {
    public int minPathSum(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }

        int M = grid.length;
        int N = grid[0].length;
        int[][] sum = new int[M][N];

        sum[0][0] = grid[0][0];

        for (int i = 1; i < M; i++) {
            sum[i][0] = sum[i - 1][0] + grid[i][0];
        }

        for (int i = 1; i < N; i++) {
            sum[0][i] = sum[0][i - 1] + grid[0][i];
        }

        for (int i = 1; i < M; i++) {
            for (int j = 1; j < N; j++) {
                sum[i][j] = Math.min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j];
            }
        }

        return sum[M - 1][N - 1];
    }
}

複製代碼

K - 1 distinct characters

  • 問題: 給一個字符串和一個整數數字
  • 輸入: inputString = "awaglk" num = 4
  • 輸出: ["awag"]
  • 思路: 雙指針, 1個指針固定頭, 另外一個直接
import java.util.*;
public class Solution {
    public static List<String> Kdistinct(String s, int k) {
		List<String> res = new ArrayList<>();
        if (s == null || s.length() == 0) {
            return res;
        }   
        int size = s.length();
        int[] count = new int[128];
        int distinctCount = 0;
        
        for (int i = 0; i < size; i++) {
		    Arrays.fill(count, 0);
			distinctCount = 0;
			for (int j = i; j < size; j++) {
				if (count[s.charAt(j)] == 0) {
                    distinctCount++;
                }
				System.out.println("i: " + i);
				System.out.println("j: " + j);
				System.out.println("distinct: " + distinctCount);
				if (distinctCount == k - 1 && j - i + 1== k) {
					res.add(s.substring(i, j + 1));
                }
				count[s.charAt(j)]++;
			}
        }
        
        return res;
    }
	
	public static void main(String[] args) {
        int n = 4;
		String input = "awagkmg";
		List<String> res = Kdistinct(input, n);
		for (String s : res) {	
        	System.out.println(s);
		}
    }
}
複製代碼

K-Substring with K different characters

public class Solution {
    /** * @param stringIn: The original string. * @param K: The length of substrings. * @return: return the count of substring of length K and exactly K distinct characters. */
    public int KSubstring(String stringIn, int K) {
        if (stringIn == null || stringIn.length() == 0 || K <= 0) {
            return 0;
        }
        int count = 0;
        HashMap<Character, Integer> charMap = new HashMap<>();
        HashSet<String> resultSet = new HashSet<String>();
        int len = stringIn.length();
        int j = 0;
        for (int i = 0; i < len; i++) {
            while (j < len && charMap.size() < K) {
                char c = stringIn.charAt(j);
                if (charMap.containsKey(c)) {
                    break;
                }
                charMap.put(c, 1);
                j++;
                // size == k是保證了子串長度爲k
                if (charMap.size() == K) {
                    resultSet.add(stringIn.substring(i, j));
                }
            }
            charMap.remove(stringIn.charAt(i));
        }
        return resultSet.size();
    }
}
複製代碼

937. Reorder Log Files

  • 問題: 本質上是字符串的字典序比較 分爲三種狀況討論 identifier > letter > digit
  • 思路: 自定義一個Comparator進行比較
class Solution {
    public String[] reorderLogFiles(String[] logs) {

        Comparator<String> com = new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                int s1Start = s1.indexOf(' ');
                int s2Start = s2.indexOf(' ');
                char s1Char = s1.charAt(s1Start + 1);
                char s2Char = s2.charAt(s2Start + 1);

                if (s1Char <= '9') {
                    if (s2Char <= '9') { // natural order
                        return 0;
                    } else { // s1 is digit-log, s2 is letter-log
                        return 1;
                    }
                }
                if (s2Char <= '9') { // s2 is digit-log, s1 is letter-log
                    return -1;
                }

                // s1 and s2 are both letter-log
                int preCompute = s1.substring(s1Start + 1).compareTo(s2.substring(s2Start + 1));
                // ignore identifier letter-logs are ordered tie
                if (preCompute == 0) {
                    return s1.substring(0, s1Start).compareTo(s2.substring(0, s2Start));
                }

                return preCompute;
            }
        };

        Arrays.sort(logs, com);
        return logs;
    }
}
複製代碼
相關文章
相關標籤/搜索