2018 12 08 ARTS(8)

什么是 ARTS
Algorithm:每周至少做一个leetcode的算法题;
Review:阅读并点评至少一篇英文技术文章;
Tip/Tech:学习至少一个技术技巧;
Share:分享一篇有观点和思考的技术文章;

Algorithm 算法题

9. 回文数

https://leetcode-cn.com/problems/palindrome-number/description/
这道题属于简单的,基本难度没啥,基本的做法就是的数字转字符串,字符串转字符数组,然后进行遍历比较世间复杂度就是O(n),这里遍历一半就足够,因为可以根据index和length来把首位的字符串分别比较,所以遍历到一般就足够了。代码足够简单

 public boolean isPalindrome(int x) {
    String xString = "" + x;
    if (xString==null||xString.length()==0) {
        return false;
    }
    int length = xString.length();
    int length2 = xString.length() / 2;
    char[] newArray = xString.toCharArray();
    for (int i = 0; i < length; i++) {
        if (newArray[i] != newArray[length-i-1]) {
            return false;
        }
    }
    return true;
}

进阶倒是挺有意思的,因为进阶就是让你寻找的可以逐个遍历数字的每一位的方法,很惭愧我是真的没想到很好的方法,倒是在别人的提交记录里看到了一个很好方法,这里分享出代码:

int s = 0;
while (s <= x) {
     s = s * 10 + x % 10;
     if (s == x || s == x / 10) { //分别处理整数长度是奇数或者偶数的情况
         return true;
     }
     x /= 10;
 }
return false;
234 回文链表

https://leetcode-cn.com/problems/palindrome-linked-list/description/
这个我的做法就是链表转list,因为想到会有比较多的get操作,所以我使用的是ArrayList的这个数据结构,提交的只能算是一般吧,代码:

public boolean isPalindrome(ListNode head) {
   if (head == null) {
       return true;
   } 
   ListNode nextNode = head.next;
   ArrayList<Integer> list = new ArrayList<Integer>();
   list.add(head.val);
   while (nextNode != null) {
       list.add(nextNode.val);
        nextNode = nextNode.next;
   }

   int length = list.size();
   for (int i = 0; i < length / 2; i++) {
       int before = list.get(i);
       int after = list.get(length - i -1);
       if (before != after) {
           return false;
       }
   }
   return true;
}
947 移除最多的同行或同列石头

https://leetcode-cn.com/contest/weekly-contest-112/problems/most-stones-removed-with-same-row-or-column/
这道题我是真的不会,后来还是去社区里面提问,在里面的社友的提示下找到了解题的思路,要用到一种叫并查集的算法设计,代码还在coding,随后提交,通过就贴上。这道题我是真的要要放弃了,我第一次做一道算法题做了两天,我去,从高中到现在第一次有这中要死了的感觉啊,等于整个周末献给了这道题了。
最后看了些关于并查集的文章啊,书啊,才真正做完了这道题目,数据结构换了三个,真的累了,甚至有点累的连思路都不想说了,因为我看到的关于并查集的思想和文章真的不是几句话就能写完的。 而且我自己总结的这个也不是那么简单就能写完的。直接上代码吧,这是原始的代码,还没什么优化,但是根据我这几天看到的,其实并查集这些只是开始,优化才是大头:

public static int removeStonesMineThird(int[][] stones) {
    int length = stones.length;
    //存放根节点的数组
    int[] root = new int[length];
    for (int i = 0; i < length; i++) {
        root[i] = i;
    }

    for (int i = 0; i < length; i++) {
        for (int j = i + 1; j < length; j++) {
        	 //找出x轴相等或者y轴相等的点,我把这样的两个点称为相连的点。
            if (stones[i][0] == stones[j][0] || stones[i][1] == stones[j][1]) {
                unionThird(i, j, root);
            }
        }
    }
    HashSet<Integer> rootSet = new HashSet<>();
    for (int i = 0; i < length; i++) {
        rootSet.add(root[i]);

    }
    return length - rootSet.size();
}

//设置的根节点的数值,每次都要把之前的根节点的数值进行更新。这个代码但看代码其实很难理解的,如果你真的有兴趣的话,你必须动手写一写才行,不然是估计很难理解吧。
public static void unionThird(int iIndex, int jIndex, int[] root) {
    int length = root.length;
    for (int i = 0; i < length; i++) {
        if (root[i] == root[iIndex] && i != iIndex) {
            root[i] = root[jIndex];
        }
    }
    root[iIndex] = root[jIndex];
}

首先题目的意思就是说,比如说有两个石头,他们的X轴或者Y轴是在一条线上的,那么这两个石头的某个点就有可能被移除。那么ok,到底哪个点会被移除?这个取决于题目的条件:最多移除的次数。因为这个条件,所以有了移除的顺序。当然移除的顺序是根本不用你关心的,只关心最后需要移动几次就行了。当然,你心里还是要明白,这个其实是有移除的顺序在里面的,只不过咱们不用记录。
最后到底需要移动几次,意思就是除了根节点不用移动,其他的节点都是要被移走。所以只要找出根节点,然后用数组的长度相减就得出了答案。


Review 阅读并点评至少一篇英文技术文

How to start working with Lambda Expressions in Java
正儿八经的技术文章啊,从入门到精通啊。


Tip/Tech:学习至少一个技术技巧

并查集的算法设计,虽然没有真正的精通,但是也算是做出一道题。
一些关于并查集的文章:
首先推荐:《算法(第四版 Java描述)》1.5 案例研究:union-find 算法
java编程实现并查集的路径压缩代码详解
数据结构–并查集的原理及实现
重点推荐:并查集Java实现
快速并查集(Java实现)
并查集详解 ——图文解说,简单易懂(转) 不推荐
并查集(Union-Find) 应用举例 — 基础篇
并查集(Union-Find)算法介绍


Share:分享一篇有观点和思考的技术文章

Robots That Draw(作画机器人)
以后咱们的作画的门槛会不会降低很多,以后在我们的唯一作画的门槛就是所谓的想象力了。
其实我开始想到作画机器人的想法是在看到雨果之后,里面的机器人在比较简陋的零件下都完成了一幅不错的话,当然这里面是编剧和道具组的功劳。相信有一天我们的只要有足够的想象力,就可以拥有足够优秀的作品。
Software Engineering is different from Programming
软件工程师不同于敲代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值