最近参加了耗子叔的ARTS100天打卡活动,每周一次。本周打卡为第一周。希望能够借助ARTS打卡活动养成良好的习惯,能够在技术和毅力等多方面有进步,并且能克服拖延症。

什么是ARTS

ARTS是耗子发起的一项打卡活动,每周要完成一个ARTS打卡一次。

以ARTS分别表示为

  • A-Algorithm:每周至少做LeetCode一道算法题;
  • R-Review:每周至少阅读一篇英文文章,学习英文的同时学习技术;
  • T-Tip:每周至少学习一个小技巧;
  • S-Share:每周分享一篇有观点和思考的技术文章;

除了以上的内容外,自己给自己加了点料:在Algorithm中分别用Java和Python实现,并研究其用到的知识点及算法知识,在此基础上每周做一道数据库的题;每两周需要至少一篇的总结博客输出。

Algorithm

描述

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example

输入:nums = [2, 7, 11, 15], target = 9

输出:[0,1],因为nums[0] + nums[1] == target

解法

这个是比较简单的题目了,不考虑时间的情况下可以考虑暴力解法,如果考虑时间的话则需要优化算法。

  • 暴力解法:对数组做双层for循环,按个寻找满足条件的解,时间复杂度为O(n2),数据量过大时则会时间超越上限;
  • 利用Map或者dict减少时间复杂度,保存当前target-当前元素以及当前索引值;

Java版

class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer,Integer> tmp = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (tmp.containsKey(nums[i])) {
return new int[] {tmp.get(nums[i]), i};
}
tmp.put(target - nums[i], i);

}
return new int[2];
}
}

Python版

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
tmp_dic = {}
for i in range(len(nums)):
if nums[i] in tmp_dic:
return [tmp_dic.get(nums[i]), i]
tmp_dic[target - nums[i]] = i
语言 Runtime Memory
Java 4ms 39.8M
Python 40ms 14.6M

Database

随机到了一道很简单的题目,只涉及到了OR关键字。题目描述如下:

查询Word表中满足area > 3000000 或者 population > 25000000 的城市的name,population及area。

查询语句如下:

SELECT 
name, population,area
FROM
World
WHERE
area > 3000000 OR population > 25000000

题目很简单,看了一下LeetCode上的标准解答,有一种解法是利用表合并,即查询分别满足一个条件的表,并把结果进行合并,涉及到的关键字是UNION,查询语句如下:

SELECT
name, population, area
FROM
World
WHERE
area > 3000000
UNION
SELECT
name, population, area
FROM
World
WHERE
population > 25000000

Review

本周阅读的英文文章是来自Medium的一篇文章Shape Drawables,Shape Drawables可以替换png图片以减少加载及绘制时间,还可以减小apk本身的大小。

Android的开放性决定了应用需要适配不同大小屏幕,在使用jpg或者png图片做屏幕适配时,需要设计师做针对不同屏幕分辨率的图片,并拷贝到对应的资源文件中。也就是说同一张不同大小的图片需要保存很多份。为了避免上述情况,可以使用xml代替jpg和png图片。

ShapeDrawable是Drawable的子类,可以通过在drawable文件夹中新建根标签为shape的xml文件,并在layout文件中引用得到,xml文件大致内容如下:

<shape 
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<corners android:radius="8dp" />
<!--渐变色-->
<gradient />
<padding android:bottom="2dp" />
<solid android:color="@color/colorPrimaryDark" />
<size
android:height="16dp"
android:width="16dp" />
<stroke android:width="2dp" />
</shape>
  • android:shape可选项有linerectangleovalring等;
  • stroke可以理解成画笔;

xml文件建立虚线ShapeDrawable时,需要用到stroke item下的dashWidthdashGap分别表示实线宽度及空隙宽度。还需要注意的是size的宽度必须要大于stroke的宽度,否则无法显示虚线;

Tip

  1. 分享一个git相关的小技巧的,从同事那学习的,确实在代码合入的时候帮助很大;

    假如本地有三个未push到远程的节点A、B、C,具体如下:

    commit-state

    git log记录如下:

    commit af75163b2dd46891ccef6989a9c661e001d372f5 (HEAD -> master)
    Author: Cherlas <vm@li.cm>
    Date: Sun Mar 24 10:53:18 2019 +0800

    commitA

    commit ab2b7b369d5e6f79626850c602a05b5101c4fd49
    Author: Cherlas <vm@li.cm>
    Date: Sun Mar 24 10:52:48 2019 +0800

    commitB

    commit 1b0a9a519a83f9771ef57a60084e7a58e365468c
    Author: Cherlas <vm@li.cm>
    Date: Sun Mar 24 10:52:11 2019 +0800

    commitC

    如果仅仅要修改B节点而不影响A和C,则操作如下:

    git rebase -i 1b0a9a519a83f9771ef57a60084e7a58e365468c

    上述命令中的节点号为要修改的节点的父节点即C节点的编号,上述命令执行后会有vim编辑提示如下:

    pick ab2b7b3 commitB
    pick af75163 commitA

    # Rebase 1b0a9a5..af75163 onto 1b0a9a5 (2 commands)

    其中比较重要的是pick关键词,可以修改此关键词达到修改、删除及合并等操作:

    关键词 含义
    pick 保持当前节点所有内容不变
    reword 仅修改该节点的commit message
    edit 可以修改提交内容及commit message
    squash 当前节点和上一节点合并
    break rebase到当前节点时停留,之后需要手动rebase --continue
    drop 删除当前节点,如果vim编辑框中的某一节点所在的行删除也可以达到同样的效果

    把vim编辑内容中commitB对应的pick修改为edit保存并推出,git会rebase到commitB节点并停留,提示如下:

    Stopped at ab2b7b3...  commitB
    You can amend the commit now, with

    git commit --amend
    Once you are satisfied with your changes, run

    git rebase --continue

    此时就可以直接修改B节点的内容,并在修改之后进行commit 打patch并进行rebase即可:

    touch commitB_edit
    git add commitB_edit
    git commit --amend
    git rebase --continue

    Share

    本周分享的文章的文章时来自Mediun中AndroidPub板块中的关于MVM及MVVM的一篇文章:

    Why to choose MVVM over MVP — Android Architecture

    主要讲了Architecture的定义:简单定义为坚决代码编写过程中代码耦合性较强等问题的一种方法或模式。

    文章中讲到了MVP的缺点:Presenter和View之间互有对方的引用(评论中也有人反驳这一点),给测试及代码分离等带来困难。而MVVM模式中的ViewModule则只对外暴露数据而不知道数据具体是谁用,单个的View(Activity)也可以有多个ViewModule的实例,在可测试性及代码耦合性方面要优于Presenter。

    打卡完毕,感觉相当的可以,后面也会给自己适当的再加一些内容,Fighting…