首页 > 学院 > 开发设计 > 正文

5th Feb: 刷题笔记

2019-11-11 05:01:22
字体:
来源:转载
供稿:网友

*************************************************************************************************************************

*              感谢ZL同学的监督,是我坚持每天完成计划的动力                                                                         *

*************************************************************************************************************************

387. First Unique Character in a String

Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.Examples:s = "leetcode"return 0.s = "loveleetcode",return 2.Note: You may assume the string contain only lowercase letters.

自己想的方法:利用一个hashtable记录已经遇到的char,接着如果重复出现的话,把value置成-1。然后找values()里面除了-1最小的值就好了。

做这道题的时候,遇到的困难是values()返回的是一个Collection。这个Collection的作用是,只能使用exhanced for去遍历,却不能转换成List或者其它子类。所以,不能使用Collections.sort去做。

public class Solution {    public int firstUniqChar(String s) {        if (s == null) {            return -1;        }                 if (s.length() == 1) {            return 0;        }                //use the hashtable to record        HashMap<Character, Integer> WordIndex = new HashMap<Character, Integer>();                for (int i = 0; i < s.length(); i++) {            if (wordIndex.containsKey(s.charAt(i))) {                wordIndex.put(s.charAt(i), -1);            } else {                wordIndex.put(s.charAt(i), i);            }        }                int min = Integer.MAX_VALUE;                for (Integer tmp : wordIndex.values()) {            if (tmp != -1) {                min = tmp < min ? tmp : min;            }        }                if (min == Integer.MAX_VALUE) {            return -1;        }                return min;    }}然而,比较简单的做法有两个:第一个方法,利用字典HashTable的做法,字母和出现次数对。再遍历一次链表,找出最先只出现一次的字母;第二个方法,利用String类提供的firstIndex和lastIndex的方法。如果一个字母有重复的话,两个函数的返回值肯定不一样。找到返回相同值的最小值即可。

第一个方法代码 (明天写):

第二个方法代码(明天写):

155. Min Stack

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.push(x) -- Push element x onto stack.pop() -- Removes the element on top of the stack.top() -- Get the top element.getMin() -- Retrieve the minimum element in the stack.Example:MinStack minStack = new MinStack();minStack.push(-2);minStack.push(0);minStack.push(-3);minStack.getMin();   --> Returns -3.minStack.pop();minStack.top();      --> Returns 0.minStack.getMin();   --> Returns -2.

这题做错的地方:对于getMin函数不能使用sort,直接使用Collections.min即可。由于java已经弃用了Stack,所以这道题用LinkedList实现即可。但是使用LinkedList实现Stack需要注意,使用addFirst和removeFirst比Last要好。因为自己实现链表的时候也知道,当addLast和removeLast的话,需要遍历整个链表,十分低效且无谓。

代码如下:

public class MinStack {    PRivate LinkedList<Integer> storage;        /** initialize your data structure here. */    public MinStack() {        this.storage = new LinkedList<Integer>();    }        public void push(int x) {        storage.addFirst(x);    }        public void pop() {        storage.removeFirst();    }        public int top() {        int ans = storage.peekFirst();        return ans;    }        public int getMin() {        return Collections.min(storage);    }}/** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */

42. Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.这题一开始的思考方向错了,后来看了烙印网站的视频,其实很好理解。首先,某个towel (bar)所能储存的水量其实是当前水桶的“短板” - 当前bar的高度决定的。但是,并不是所有的bar都能储水。所以我们首先需要判断这个bar能不能储水。如果能储水,就把水量加到要返回的水量总和当中。

怎么判断当前bar能不能储水呢?

这就是比较tricky的地方了。主要看这个bar的左边的所有bar中最高的bar是否能高过这个bar且右边的所有bar中最高的bar是否能高过这个bar。如果两边都满足,这个bar能储水。否则,直接跳过这个bar即可。

public class Solution {    public int trap(int[] height) {        if (height == null || height.length < 3) {            return 0;        }                int[] maxHeightLeft = new int[height.length];        int[] maxHeightRight = new int[height.length];                maxHeightLeft[0] = 0;        maxHeightRight[height.length - 1] = 0;                int maxHeight = 0;        //fill in those two arrays        for (int i = 1; i < height.length; i++) {            maxHeight = 0;            for (int j = i - 1; j > -1; j--) {                maxHeight = height[j] > maxHeight ? height[j] : maxHeight;            }            maxHeightLeft[i] = maxHeight;        }                for (int i = 0; i < height.length - 1; i++) {            maxHeight = 0;            for (int j = i + 1; j < height.length; j++) {                maxHeight = height[j] > maxHeight ? height[j] : maxHeight;            }            maxHeightRight[i] = maxHeight;        }                //simple logic        int trap = 0;                for (int index = 0; index < height.length; index++) {            if (height[index] > maxHeightLeft[index] || height[index] > maxHeightRight[index]) {                continue;            }                        trap += (Math.min(maxHeightLeft[index], maxHeightRight[index]) - height[index]);        }                return trap;    }}116. Populating Next Right Pointers in Each NodeGiven a binary tree    struct TreeLinkNode {      TreeLinkNode *left;      TreeLinkNode *right;      TreeLinkNode *next;    }Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.Initially, all next pointers are set to NULL.Note:You may only use constant extra space.You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).For example,Given the following perfect binary tree,         1       /  /      2    3     / /  / /    4  5  6  7After calling your function, the tree should look like:         1 -> NULL       /  /      2 -> 3 -> NULL     / /  / /    4->5->6->7 -> NULL117. Populating Next Right Pointers in Each Node IIFollow up for problem "Populating Next Right Pointers in Each Node".What if the given tree could be any binary tree? Would your previous solution still work?Note:You may only use constant extra space.For example,Given the following binary tree,         1       /  /      2    3     / /    /    4   5    7After calling your function, the tree should look like:         1 -> NULL       /  /      2 -> 3 -> NULL     / /    /    4-> 5 -> 7 -> NULL

这两题之所以结合在一起讲,是因为直接用117的代码就可以通过116的题目。116只是117的特殊形式(完全二叉树)。

看完了烙印网站 I Deserve 的视频后,这题的思路只需要记住下面的递归过程即可:

Step 1: 当前节点是叶子节点或者为null的时候返回(base case);

Step 2:链接当前节点的左右两个孩子(如果有两个孩子的话,因为step1,确保了至少有一个孩子):左孩子.right = 右孩子。并且把孩子与其它的同层次的孩子的right都链接了。当时这里需要这样判断逻辑:

if (有两个孩子) {

链接两个孩子,链接右孩子和root.right的左孩子或者右孩子(如果有的话)。这里自己写的时候漏了考虑:如果root的right没有孩子,当时root.right.right有呢?所以这里需要另外设置个neighbour变量,然后用while直到找到当前的左/右孩子的右边的节点为止或者遍历完所有root的neighbour。

} else {

用那个唯一的孩子,直接连接到root的neighbour的孩子(如果有)。与上述黑体字过程一致。

}

Step 3:递归调用右孩子;

Step 4:递归调用左孩子;

为什么要优先调用右孩子呢?就是为了确保上述黑体字的过程能顺利实现。否则,可能不能找完所有的neighbours. 

代码如下:

public class Solution {    public void connect(TreeLinkNode root) {        if (root == null || (root.left == null && root.right == null)) {            return;        }                if (root.left != null && root.right != null) {            root.left.next = root.right;            TreeLinkNode parentNeibour = root.next;            while (parentNeibour != null) {                if (parentNeibour.left != null || parentNeibour.right != null) {                    root.right.next = (parentNeibour.left == null ? parentNeibour.right : parentNeibour.left);                    break;                }                parentNeibour = parentNeibour.next;            }        } else {            TreeLinkNode child = (root.left != null ? root.left : root.right);            TreeLinkNode parentNeibour = root.next;            while (parentNeibour != null) {                if (parentNeibour.left != null || parentNeibour.right != null) {                    child.next = (parentNeibour.left == null ? parentNeibour.right : parentNeibour.left);                    break;                }                parentNeibour = parentNeibour.next;            }        }                connect(root.right);        connect(root.left);    }}160. Intersection of Two Linked Lists

Write a program to find the node at which the intersection of two singly linked lists begins.For example, the following two linked lists:A:          a1 → a2                   ↘                     c1 → c2 → c3                   ↗            B:     b1 → b2 → b3begin to intersect at node c1.Notes:If the two linked lists have no intersection at all, return null.The linked lists must retain their original structure after the function returns.You may assume there are no cycles anywhere in the entire linked structure.Your code should preferably run in O(n) time and use only O(1) memory.

这道题其实很tricky,做这道题之前,需要知道cycleLinkedList的判断标准:快慢指针能否相遇。

且如何找到circle的起点:slow.next = head的时候,head就是起点,否则一直:head = head.next; slow = slow.next;

这些在http://blog.csdn.net/firehotest/article/details/52665467 提到过,知道了这些之后,这道题就可以很tricky地解决了。把headB放到headA之后,然后看看有没有cycle。如果有就是有交叉点啦。然后通过slow.next = head的方法找到交叉点。接着返回交叉点即可。

代码:

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { *         val = x; *         next = null; *     } * } */public class Solution {    private ListNode cycleLinkedListII(ListNode head) {        if (head == null || head.next == null) {            return null;        }                ListNode fast = head.next;        ListNode slow = head;                while (fast != slow) {            if (fast == null || fast.next == null) {                return null;            }            fast = fast.next.next;            slow = slow.next;        }                while (head != slow.next) {            head = head.next;            slow = slow.next;        }                return head;    }            public ListNode getIntersectionNode(ListNode headA, ListNode headB) {        if (headA == null || headB == null) {            return null;        }                ListNode cur = headA;                while (cur.next != null) {            cur = cur.next;        }                cur.next = headB;                ListNode result = cycleLinkedListII(headA);                cur.next = null;                return result;            }}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表