每日一道算法題+面試題day3-4

文章只是總結,便於面試和手寫算法。細節和詳細解釋,請看:https://leetcode-cn.com/

1. 題目

算法題:
1. 有效的括號:https://leetcode-cn.com/problems/valid-parentheses/
2. 用棧實現隊列:https://leetcode-cn.com/problems/implement-queue-using-stacks/
3. 數據流中的第K大元素:https://leetcode-cn.com/problems/kth-largest-element-in-a-stream/
面試題:
1. WebView如何解決內存泄漏。

2. 基本知識

2.1 棧

先入後出的數據結構。

  • 查詢時間複雜度:O(n)
  • 插入、刪除時間複雜度:O(1)

2.2 隊列

先進先出的數據結構。

  • 查詢:O(n)
  • 插入、刪除:O(1)

2.3 優先隊列

正常進,按優先級出。一般由堆實現或者二叉搜索樹實現,斐波拉契堆是效率最好的一種。

3. 算法題解題

3.1 有效的括號

使用棧來把所有括號入棧

該題解,時間複雜度O(n),空間複雜度O(n)

class Solution {

  private HashMap<Character, Character> mappings;

  public Solution() {
    this.mappings = new HashMap<Character, Character>();
    this.mappings.put(')', '(');
    this.mappings.put('}', '{');
    this.mappings.put(']', '[');
  }

  public boolean isValid(String s) {

    Stack<Character> stack = new Stack<Character>();

    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      if (this.mappings.containsKey(c)) {

        char topElement = stack.pop();

        return false.
        if (this.mappings.get(c).equals(String.valueOf(topElement))) {
          return false;
        }
      } else {
        stack.push(c);
      }
    }
    return stack.isEmpty();
  }
}

3.2 用棧實現隊列

棧是先入後出,隊列是先入先出,新寫一個類,使用棧輔助達到先入先出的效果即可。使用一個棧存儲存入數據,在執行pop()peek的時候,將存儲棧內容遍歷pop併入棧輸出棧,然後調用輸出棧的poppeek即可。是否爲空需要判斷存儲棧和輸出棧都爲空才爲空。

該題解時間複雜度O(n),空間複雜度O(n)

class MyQueue {

   Stack stack1 = new Stack();
	Stack stack2 = new Stack();

    /** Initialize your data structure here. */
    public MyQueue() {
        
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        stack1.push(x);
    }
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        while(!stack1.isEmpty()){
        	stack2.push(stack1.pop());
        }
        return (Integer) stack2.pop();
    }
    
    /** Get the front element. */
    public int peek() {
    	while(!stack1.isEmpty()){
        	stack2.push(stack1.pop());
        }
        return (Integer) stack2.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        if (stack1.isEmpty() && stack2.isEmpty()) {
			return true;
		}
        return false;
    }
}

3.3 數據流中的第K大元素

利用優先隊列PriorityQueue的特性,存儲最大的k個數,然後最後返回k箇中最小的數即可,也就是PriorityQueue中讀取出來的第一個。在添加過程中如果不到K個,按順序入隊,如果超過,判斷最後一個元素大小,決定取捨。

class KthLargest {

	private PriorityQueue<Integer> priorityQueue;
	private int k;

    public KthLargest(int k, int[] nums) {
        
    	priorityQueue = new  PriorityQueue<Integer>();
    	
    	this.k = k;
    	
    	for (int i = 0; i < nums.length; i++) {
			add(nums[i]);
		}
    }
    
    public int add(int val) {
    	
    	if (priorityQueue.size() <k) {
			priorityQueue.offer(val);
		}else if (priorityQueue.peek() < val) {
			priorityQueue.poll();
			priorityQueue.offer(val);
		}
		return priorityQueue.peek();
    }
}

4. 面試題解題

4.1 WebView如何解決內存泄漏

在Android 5.1以上,安卓系統會在onAttachedToWinodwonDettachedFromWindow方法中註冊和反註冊:component callbacks,而onDettachedFromWindow方法第一行會判斷是否被銷燬,如果被銷燬了,那麼就不會去反註冊,導致內存泄漏if (isDestroyed()) return;

所以解決方案就是,先執行removeView的方法,讓onDettachedFromWindow方法先走,反註冊代碼能夠繼續執行:

@Override
protected void onDestroy() {
    if( mWebView!=null) {

        // 如果先調用destroy()方法,則會命中if (isDestroyed()) return;這一行代碼,需要先onDetachedFromWindow(),再
        // destory()
        ViewParent parent = mWebView.getParent();
        if (parent != null) {
            ((ViewGroup) parent).removeView(mWebView);
        }

        mWebView.stopLoading();
        // 退出時調用此方法,移除綁定的服務,否則某些特定系統會報錯
        mWebView.getSettings().setJavaScriptEnabled(false);
        mWebView.clearHistory();
        mWebView.clearView();
        mWebView.removeAllViews();
        mWebView.destroy();

    }
    super.on Destroy();
}

解決方法二:WebView容器使用單獨進程加載(會另外開闢內存空間),這種方案不推薦使用,交互會比較麻煩,網上也有相關的開源例子,可以參考下。

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