美文网首页
数组链表算法思路一

数组链表算法思路一

作者: 你值得拥有更好的12138 | 来源:发表于2020-02-01 22:13 被阅读0次

解题方法:

  • 快慢指针推进程序降低复杂度
  • HashMap,优先队列,双端队列辅助统计计算
  • 快排思想完成对半查找,无需进行构造搜索树
  • 使用kmp算法进行子串查找
  • 遇到字母统计使用hash思想进行统计
  • 遇到数字可以使用异或运算

思维

首先请放弃你那种暴力法,即动不动就上双重循环的思维方式。
然后更多的使用切分和线性的方式去做数组或者链表的题,在动态规划中更是这样。

例题一

解题方法:使用快慢指针+Map进行辅助统计计算

总结一句话:连续不重复字串最长

题目内容
LeetCode 第 03 题:给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。

示例 1
输入:"abcabcbb"
输出:3
解释:因为无重复字符的最长子串是"abc",其长度为3。

解题思路:

使用快慢指针(slow,fast)的方式,当fast前进一步就向Map中进行put一个元素,当遇到Map中包含这个元素时,就进行删除。

怎么删除呢?
使用Map获取相同字符的位置然后加一,并且更新slow指针

怎么计算长度呢?
快慢指针位置相减加一

下面的解题方法有两种:
1.使用指针一个一个删除这种方式显然是很多次是多余
2.使用Map进行跳跃,那就可以省去了很多次的删除过程

public class ContinuousNonRepetitionString {
    
    public static void main(String[] args) {
        String[] data = {"d","e","a","d","c","a","q"};
        System.out.println(new ContinuousNonRepetitionString().length(data));
        System.out.println(new ContinuousNonRepetitionString().lengthStep(data));
    }

    /**
     * 使用Map快速跳转慢指针的方法
     * @param nums
     * @return
     */
    private int length(String[] nums){
        int i = 0;
        int j = 0;
        Map<String,Integer> temp = new HashMap<>();
        int max = 0;
        for(;j<nums.length;j++){
            if(temp.containsKey(nums[j])){
                i = temp.get(nums[j])+1;
            }
            temp.put(nums[j],j);
            max=Math.max(max,j-i+1);
        }
        return max;
    }


    /**
     * 使用循环删除的方式,更新慢指针
     * @param nums
     * @return
     */
    private int lengthStep(String[] nums){
        int i = 0;
        int j = 0;
        Set<String> temp = new HashSet<>();
        int max = 0;
        for(;j<nums.length;j++){
            while (temp.contains(nums[j])){
                temp.remove(nums[i]);
                i++;
            }
            temp.add(nums[j]);
            max=Math.max(max,j-i+1);
        }
        return max;
    }
}

例题二

解题方法:使用快排的思想进行查找,并不是把全部的元素排序

总结一句话: 找中位数

题目:
LeetCode 第 04 题:给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m+n))。
你可以假设 nums1 和 nums2 不会同时为空。

示例1
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

示例2
nums1 = [1, 2]
nums2 = [3, 4]
则中位数是 (2 + 3)/2 = 2.5

解题思路

换一种思路想:
首先将两个数组合并

然后找第k大的元素,当我们使用快速排序的时候,每排序一轮后,中间的那个元素就就是第k大元素,所以我们可以通过比较k值得大小决定向左还是向右继续比较,另一边就不需要管了。这样就降低的时间复杂度

此题有两种情况:
1.数组是奇数,中位数为 第k大的元素 k=nums.length/2 ,排序后的坐标为k-1
2.数组是偶数,中位数为 第k大和第k+1大的平均值

public class MedianQuickMethod {
    public static void main(String[] args) {
            int[] nums = {1,3,5,7,9,11,13,15};//1,3,5,7,9,15,13,11
            //15,3,5,7,9,1,13,11
            //15,13,11,7,9,1,3,5
            System.out.println(new MedianQuickMethod().findMedian(nums));
    }

    private double findMedian(int[] nums){
        int k = nums.length/2;
        if((nums.length)%2 == 0){
            double k1= quick(nums,0,nums.length-1,k);
            double k2= quick(nums,0,nums.length-1,k+1);
            return (k1+k2)/2f;

        }else {
          return   quick(nums,0,nums.length-1,k+1);
        }
    }

    private double quick(int[] nums,int low,int he,int k){
       int pivot = (int) (Math.random()*(he-low+1)+low);
//       int pivot = low;
       swap(nums,pivot,he);
       int finishPos = low;
        System.out.println("p:"+nums[he]);
       for(int i=low;i<nums.length;i++){
          if(nums[i]>nums[he]){
              swap(nums,i,finishPos);
              finishPos++;
          }
       }
       swap(nums,he,finishPos);
        System.out.println(Arrays.toString(nums));

       //第几个
       int tempk = finishPos-low+1;
        System.out.println("第k大:"+tempk + "要求:" + k);
       if(tempk==k)
           return nums[finishPos];
       else if(tempk<k)
           return quick(nums,finishPos+1,he,k-tempk);
       else
           return quick(nums,low,finishPos-1,k);
    }


    private void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

相关文章

  • 数组链表算法思路一

    解题方法: 快慢指针推进程序降低复杂度 HashMap,优先队列,双端队列辅助统计计算 快排思想完成对半查找,无需...

  • 数组链表算法思路二

    总体思路参考上一篇 数组链表算法思路一 例题: 解题方法:1.遇到字母统计使用hash思想进行统计2.遇到数字可以...

  • 数组链表算法思路三(KMP算法)

    思路 在字符串的比较中,不能双重循环的去做,时间复杂度是n^2,需要进行简化 例子:(KMP) 有s,m两个字符串...

  • 算法草稿

    常用算法集合 字符处理算法数组与查找链表树算法思路 递归、动态规划、BFS/DFS、双指针、二分法搜索数据结构的...

  • 19 删除链表的倒数第 N 个结点

    题目: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 自行解答: 算法思路: 其实算法是链表...

  • 剑指offer 从尾到头打印链表

    题目: 思路: 把链表保存进数组,将数组反转返回 代码:

  • 数据结构与算法

    数据结构 计算机存储,组织数据的方式。存数据的,而且是在内存中存 算法 算法是一种解决特定问题的思路 数组与链表的...

  • 876. 链表的中间结点

    解题思路 解法一:数组 遍历链表,并将链表中的元素存入数组A。假设一共遍历到N个元素,最后返回数组A[N/2]即可...

  • 2018-06-07

    算法笔记 1 大O算法 1:O(运算次数):表示运算最糟糕情况下 运算时间,表示算法时间的增速 2数组链表 在链表...

  • Java实现每日一道算法面试题(20):leecode23 合并

    1.算法题目 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 示例: 2.算法思路 算法思...

网友评论

      本文标题:数组链表算法思路一

      本文链接:https://www.haomeiwen.com/subject/suzxxhtx.html