LeetCode 461 617 500 476 575 637

来源:互联网 发布:古剑奇谭灵兽进阶数据 编辑:程序博客网 时间:2024/06/18 08:37

461. Hamming Distance

描述:

The Hamming distance between two integers is the number of positions at which the corresponding bits are different. Given two integers x and y, calculate the Hamming distance.

思路:

题目很简单,要求求出两个数字的海明距离,海明距离在计算机网络中有涉及,我们求出两个数字二进制的同位上数字不同的次数即可(一个是1另一个是0,或一个是0另一个是1两种不同情况)。

题解:

public class Solution {    public int hammingDistance(int x, int y) {        return Integer.bitCount(x ^ y);    }}
**解释:**首先将两个数组x和y做异或,异或得到的是同位不同为1的情况,再计算这个异或数字的1的个数即是海明距离。JAVA在Integer包中的bitCount方法可以计算数字二进制的1的个数。调用之,这道题一行水过。这道题虽然水,但是有很多种方法,比如下面这个题解中用C++的n&(n-1)来做:
class Solution {public:    int hammingDistance(int x, int y) {        int dist = 0, n = x ^ y;        while (n) {            ++dist;            n &= n - 1;        }        return dist;    }};
这份题解让我特别好奇n&(n-1)有哪些作用,百度之,发现主要有以下作用:1. 每次运算去掉n最右侧的1 2. 用n&(n-1)==0判断一个数字是不是2的幂除此之外,发现n&-n是取得n最右边的1的技巧n&-n==n也可以判断是不是2的幂。##617. Merge Two Binary Trees**描述:**>Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not.You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree.**思路:**题目的意思是将两个二叉树合并,相同节点的值相加。这个题的难点在于这两棵树可能是形状不同的树,我们的一个思路是将树进行扩展,如果一棵树有该节点另一棵树没有,则创建一个空节点并赋值0。这样是不影响计算。**题解:**
public class Solution {    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {        if(t1==null&&t2==null)            return null;        if(t1==null&&t2!=null)            t1 = new TreeNode(0);        if(t2==null&&t1!=null)            t2 = new TreeNode(0);        t1.val=t1.val+t2.val;        t1.left=mergeTrees(t1.left,t2.left);        t1.right=mergeTrees(t1.right,t2.right);        return t1;    }}
**解释:**我觉得这道题用队列模拟递归也可以,代码估计要多一些。我用的是递归算法,6行代码,前三行做判断情况,之后先加得到该节点的值,然后递归左右两边。递归算法就是代码少想的久,想清楚了轻松水过。##500. Keyboard Row**描述:**>Given a List of words, return the words that can be typed using letters of alphabet on only one row’s of American keyboard like the image below.![这里写图片描述](http://img.blog.csdn.net/20170726093547335?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUXVpbm5Ob3JyaXM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)**思路:**这道题目有点意思。输出使用同一行字母的单词,开始的时候根据从前写C++的ACM经验我将它们分成三个char[]来讨论,后来怎么想都没有好方法,打开discuss看到大神的一行代码,恍然大悟,用正则甚是简单。从这个题中得出一个结论,字符串的题多考虑考虑正则匹配,有奇效。**题解:**
public class Solution {    public String[] findWords(String[] words) {        int count = words.length;        for (int i = 0; i < words.length; i++) {            if (!words[i].toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")) {                words[i] = "0";                count--;            }        }        String[] resarr = new String[count];        count = 0;        for (int i = 0; i < words.length; i++)            if (words[i] != "0")                resarr[count++] = words[i];        return resarr;    }}

解释:

首先用正则表达式匹配字符串,不符合条件的字串都被标记为“0”。最后创建数组,把字符串放到数组中。思路不难,主要是怎么处理字符串是最要思考的地方。有的大神用了JAVA1.8中的Stream类来一行过,我还看不大懂,先mark,以后留着学习。

public String[] findWords(String[] words) {    return Stream.of(words).filter(s -> s.toLowerCase().matches("[qwertyuiop]*|[asdfghjkl]*|[zxcvbnm]*")).toArray(String[]::new);}

476. Number Complement

描述:

Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.
Note:
The given integer is guaranteed to fit within the range of a 32-bit signed integer.
You could assume no leading zero bit in the integer’s binary representation.

思路:

这道题要求输出一个数字的二进制的0与1替换后的数字,开始想用-n,后来发现补码很麻烦,采用了直接操作转换的方法,估计Integer中有很多操作的方法。

题解:

public class Solution {    public int findComplement(int num) {        return (int)(num ^ (long) Math.pow(2, 32 - Integer.numberOfLeadingZeros(num)) - 1);    }}

解释:

一行JAVA代码,解法不唯一。首先我用 32 - Integer.numberOfLeadingZeros(num)求得该数字最高位左边0的个数,再用32去减得到二进制数字位数。再求2的位数次方的值-1得到一个与原数字有相同个二进制位的全1的数。再异或得出结果。这里WA了一次,注意范围会爆,要用long先运算。

575. Distribute Candies

描述:

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

思路:

这道题说兄妹分复数个糖,不难看出一些基本的思路,如果有2个糖,则兄妹一人一个,两个以上则妹妹必定有一个,再用哥哥可以拿到的糖和1个的糖做一些运算,这样可以做,但是我想说的不是这种算法,这种算法的代码贴在下面,是我第一次的代码,可以AC。

public class Solution {    public int distributeCandies(int[] candies) {        Map<Integer, Integer> map = new HashMap<Integer, Integer>();        for (int i = 0; i < candies.length; i++) {            if (map.containsKey(candies[i]))                map.put(candies[i], map.get(candies[i]) + 1);            else                map.put(candies[i], 1);        }        int count = 0;        int brotherFull = 0;        int oneCandies = 0;        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {            int val = entry.getValue();            if (val == 1)                oneCandies++;            else {                brotherFull += val - 2;                count++;            }        }        if (brotherFull < oneCandies)            count += brotherFull + (oneCandies - brotherFull) / 2;        else            count += oneCandies;        return count;    }}

代码很长,思路也有点复杂。但是这道题可以有更巧妙的解法。

  1. 如果糖的种类小于总糖数的一半,则妹妹可以拿到所有种糖。
  2. 如果糖的种类多于总糖数的一半,则妹妹可以拿到总糖数一半数量的糖。

题解:

public class Solution {    public int distributeCandies(int[] candies) {        Set<Integer> kinds = new HashSet<>();        for (int candy : candies) kinds.add(candy);        return kinds.size() >= candies.length / 2 ? candies.length / 2 : kinds.size();    }}

解释:

既然是JAVA,那用一些数据结构也不是不行,这里用下Set的去重作用。有更简单的做法,可以在参数数据读取到一半的时候就得到结论,大家可以自己试一下。但这种题目的复杂度本来就不是很高,这种方法也轻松水过。

637. Average of Levels in Binary Tree

描述:

Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.

思路:

俗话说的好,越是短的题目越难做。这道题是求二叉树每层的平均值。我WA了两次,而且最绝望的是我WA了之后还觉得我的算法是对的(摔。我的算法是递归,先看root的值放入List中,然后每层维护自己的List,最后通过不断的/2得到均值。后来发现问题在于每层可能的节点数是不同的,对于一层有奇数个节点,我这种方法是完全不能实现的。所以我的WA答案中只有一些数据是对的,一部分是错的,这迷惑了我很久。

正确的思路是用queue来模拟递归的情况,每层分别计算。或者说这道题就是广度优先算法(BFS)的简单应用,每一层的均值算出来,直接存放进入List中。这道题提示我们,递归不行的就别硬来,想想队列。

题解:

public class Solution {    public List<Double> averageOfLevels(TreeNode root) {        List<Double> result = new ArrayList<>();        Queue<TreeNode> q = new LinkedList<>();        if(root == null) return result;        q.add(root);        while(!q.isEmpty()) {            int n = q.size();            double sum = 0.0;            for(int i = 0; i < n; i++) {                TreeNode node = q.poll();                sum += node.val;                if(node.left != null) q.offer(node.left);                if(node.right != null) q.offer(node.right);            }            result.add(sum / n);        }        return result;    }}

解释:

知道了思路这道题就很好做了,队列模拟,看一下每层的个数再算均值。

原创粉丝点击