剑指Offer(第二版):30. 包含min函数的栈(链表) 57 - II. 和为s的连续正数序列(滑动窗口) 58 - I. 翻转单词顺序 53 - I. 在排序数组中查找数字 I

剑指Offer(第二版):30. 包含min函数的栈(链表) 57 - II. 和为s的连续正数序列(滑动窗口) 58 - I. 翻转单词顺序 53 - I. 在排序数组中查找数字 I_第1张图片

/**
解题思路:首先我们想到栈是"先入后出",因此我们通过链表模拟
栈时,后放入的节点反而做为链表头,这样我们做相关操作时只要
链表头的节点就可以了,而对于取最小值,我们只需要再定义Node
时多一个属性即可。
 */
class MinStack {
     
    private class Node {
     
        int val;
        int min;
        Node next;

        private Node(int val , int min , Node next){
     
            this.val = val;
            this.min = min;
            this.next = next;
        }
    }
    private Node head;
    /** initialize your data structure here. */
    public MinStack() {
     
        
    }
    
    public void push(int x) {
     
        if(head == null)
            head = new Node(x , x , null);
        else
            head = new Node(x,Math.min(head.min,x), head);
    }
    
    public void pop() {
     
        head = head.next;
    }
    
    public int top() {
     
        return head.val;
    }
    
    public int min() {
     
        return head.min;
    }
}

/**
 * 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.min();
 */

剑指Offer(第二版):30. 包含min函数的栈(链表) 57 - II. 和为s的连续正数序列(滑动窗口) 58 - I. 翻转单词顺序 53 - I. 在排序数组中查找数字 I_第2张图片

/**
解题思路:看到这题首先想到的是滑动窗口:
首先我们选取的区间范围是:1~target-1
然后l是窗口左界,r是窗口右界,窗口中的值是连续值
我们遍历1~target-1,当窗口的数字和target,l右移,等于target时则输出
 */
class Solution {
     
    public int[][] findContinuousSequence(int target) {
     
        //首先因为我们不知道有多少数组返回,因此我们需要list
        List<int[]> list = new ArrayList<>();
        //遍历可以选取的区间范围
        for(int l=1 ,r=1 ,sum = 0 ; r<target ; r++){
     
            sum+=r;
            //当>target,就左移,直到<=target
            while(sum>target){
     
                sum-=l++;
            }
            if(sum == target){
     
                int len =r-l+1;
                int[] tmp = new int[len];
                for(int i=0 ; i<len ; i++){
     
                    tmp[i] = l+i;
                }
                list.add(tmp);
            }
        }
        //遍历list,转换成Array返回
        int len_list = list.size();
        int[][] res = new int[len_list][];
        for(int i =0 ; i<len_list ; i++){
     
            res[i] = list.get(i);
        }
        return res;
    }
}

剑指Offer(第二版):30. 包含min函数的栈(链表) 57 - II. 和为s的连续正数序列(滑动窗口) 58 - I. 翻转单词顺序 53 - I. 在排序数组中查找数字 I_第3张图片

/**
解题思路:用空格拆分字符串,然后逆向遍历
注意1:因为反转后前后空格不能要,所以我们可以通过trim()删除
注意2:为了避免多余空格,我们可以个split()分开的一个一个小的字符串在加前都trim()
注意3:我们在逆向遍历时,一定要把空的""去掉。因为按" "空格区分如果两个空格挨着,则就会出现""
 */
class Solution {
     
    public String reverseWords(String s) {
     
        //拆分
        String[] str_array = s.trim().split(" ");
        //然后创建字符串进行拼接
        StringBuffer str_rev = new StringBuffer();
        //逆向表里
        for(int i = str_array.length-1 ; i>=0 ; i--){
     
            //去除空字符
            if(str_array[i].equals(""))
                continue;
            //如果到头了,append加最后一块前,要将最后一块的空格的前后去掉
            if(i==0)
                str_rev.append(str_array[i].trim());
            else
                str_rev.append(str_array[i].trim()).append(" ");
        }
        //输出
        return str_rev.toString();
    }
}

剑指Offer(第二版):30. 包含min函数的栈(链表) 57 - II. 和为s的连续正数序列(滑动窗口) 58 - I. 翻转单词顺序 53 - I. 在排序数组中查找数字 I_第4张图片

/**
解题思路1:哈希表,但是浪费了有序这个条件
 */
// class Solution {
     
//     public int search(int[] nums, int target) {
     
//         //通过哈希表进行记录
//         Map map_search = new HashMap<>();
//         for(int m : nums){
     
//             if(map_search.containsKey(m))
//                 map_search.put(m,map_search.get(m)+1);
//             else
//                 map_search.put(m , 1);
//         }
//         return map_search.containsKey(target)?map_search.get(target):0;
//     }
// }

/**
解题思路2:二分查找法
因为有序:r永远取的>=target的索引位置,而l最终要取的是target的最左边的位置,也就是第一个target
 */
class Solution {
     
    public int search(int[] nums, int target) {
     
        int l = 0 , r = nums.length-1;
        int count =0;
        while(l<r){
     
            int mid = (l+r)/2;
            if(nums[mid]>=target)
                r = mid;     
            else
                l = mid+1;
        }
        while(l<nums.length && nums[l++]==target){
     
            count++;
        }
        return count;
    }
}

你可能感兴趣的:(#,剑指Offer(第二版),链表,数据结构)