ARTS 第9周 -0701

  • Algorithm主要是为了编程训练和学习。每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard)。进行编程训练,如果不训练你看再多的算法书,你依然不会做算法题,看完书后,你需要训练。关于做Leetcode的的优势,你可以看一下我在coolshell上的文章 Leetcode 编程训练 - 酷 壳 - CoolShell。
  • Review:主要是为了学习英文,如果你的英文不行,你基本上无缘技术高手。所以,需要你阅读并点评至少一篇英文技术文章,我个人最喜欢去的地方是http://Medium.com(需要梯子)以及各个公司的技术blog,如Netflix的。
  • Tip:主要是为了总结和归纳你在是常工作中所遇到的知识点。学习至少一个技术技巧。你在工作中遇到的问题,踩过的坑,学习的点滴知识。
  • Share:主要是为了建立你的影响力,能够输出价值观。分享一篇有观点和思考的技术文章

打卡地址

 

Algorithm 算法

88. 合并两个有序数组

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]

 

public static void merge(int[] nums1, int m, int[] nums2, int n) {
    int n1Start = 0;
    int n2Start = 0;
    while (n2Start < n) {
        if (nums1[n1Start] >= nums2[n2Start] ||  m <= n1Start ) {
            System.arraycopy(nums1, n1Start, nums1,n1Start + 1,nums1.length - n1Start - 1);
            nums1[n1Start] = nums2[n2Start];
            n2Start++;
            m++;
        }
        n1Start++;
    }
}

分析

1.首先返回的就是原数组nums1,所以没办法用一个新的数组接收返回(当然可以通过把新数组copy到nums1数组)。

2.有些情况,到了最后nums2的元素要和nums1中最后的0进行替换,但不能通过对0这个数值进行比较来替换,要应用m,这个nums1规定的有效数值长度来控制比较。

3.将nums2中的数据插入到nums1中,循环的时候只要判断nums2中的数据都放入就可以了。

难点

首先的第一个难点其实就是想到用System.arraycopy来进行数组的拷贝,我第一个想到的是拿一个新的数组来接收,然后将新数组的内容拷贝到nums1。当然新数组需要开辟新的空间。

 

public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

src:源数组; 
srcPos:源数组要复制的起始位置; 
dest:目的数组; 
destPos:目的数组放置的起始位置; 
length:复制的长度。 
注意:src 和 dest都必须是同类型或者可以进行转换类型的数组.

 

 

 

Review 回顾

暂无

 

Tip 知识点

既然IN 和 EXIST 都可以得到相同的结果,那么我们该使用IN 还是 EXIST 呢?

SELECT * FROM A WHERE cc IN (SELECT cc FROM B)
SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)

 

实际上在查询过程中,在我们对cc列建立索引的情况下,我们还需要判断表A和表B的大小。在这里例子当中,表A指的是player表,表B指的是player_ score表。

 

如果表A比表B大,那么IN子查询的效率要比EXIST子查询效率高,因为这时B表中如果对cc列进行了索引,那么IN子查询的效率就会比较高。

 

如果表A比表B小,那么使用EXIST子查询效率会更高,因为我们可以使用到A表中对cc列的索引,而不用从B中进行cc列的查询。

 

 

Share分享

HashMap在jdk1.8中加入了红黑树,在满足一定条件时,将链表转化为红黑树

树化的条件

扩容的条件有两个:

1)数组的长度达到了扩容阀值

2)桶中的链表长度达到了8,并且数组的长度小于64

 

树化的条件是:

桶中单链表的长度达到了8,并且数组的长度大于等于64。

 

当然在条件不满足的情况下,红黑树也会转化为链表

 

树化的优点

链表虽然实现简单,但是在查找的效率上只有O(n),而且我们大部分的操作都是在进行查找,在hashCode()设计的不是非常良好的情况下,碰撞冲突可能会频繁发生,链表也会变得越来越长,这个效率是非常差的。Java 8对其实现了优化,链表的节点数量在到达阈值时会转化为红黑树,这样查找所需的时间就只有O(log n)

 

主要是为了避免哈希碰撞拒绝服务攻击

从性能角度来看:解决哈希冲突时使用链表,插入和删除的效率很高,只需O(1)的时间复杂度,但对于查询而言,则需要O(n)的时间负责度。但红黑树的插入,删除,查询的最差时间复杂度为O(logn)。恶意代码可以利用大量数据与服务器交互,比如String的hashcode函数的强度很弱,有人可以很容易的构造出大量hashcode相同的String对象。如果向服务器一次提交数万个hashcode相同的字符串,服务器的查询时间过长,让服务器的CPU被大量占用当有其他更多的请求时服务器会拒绝服务。而使用红黑树可以将查询时间降低到一定的数量级,可以有效避免哈希碰撞拒绝服务攻击。

HashMap为什么树化

HashMap源码浅析(一):树化

 

 

 

 

你可能感兴趣的:(java,ARTS)