Codewars Java练习:Find the odd int

题目

Given an array, find the int that appears an odd number of times.

There will always be only one integer that appears an odd number of times.

题解

运用异或运算,异或xor满足一个特殊的性质,即a xor a == 0,因此,将整个输入数组异或起来的话,出现偶数次的数将会全部被抵消掉,仅剩下唯一的,出现了奇数次的数。

import java.util.*;
import java.io.*;

class FindOdd {
	public static int findIt(int[] a) {
		int result = 0;
		for (int w:a) {
			result ^= w;
		}
		return result;
  }
}

当然,这个实现方式最简单的代码应该是——

import static java.util.Arrays.stream;

public class FindOdd {
  public static int findIt(int[] arr) {
    return stream(arr).reduce(0, (x, y) -> x ^ y);
  }
}

和之前TwoToOne那一道题相似,运用到了stream类,不同的是,这次使用了stream类的reduce函数。

Codewars Java练习:Find the next perfect square!

题目

You might know some pretty large perfect squares. But what about the NEXT one?

Complete the findNextSquare method that finds the next integral perfect square after the one passed as a parameter. Recall that an integral perfect square is an integer n such that sqrt(n) is also an integer.

If the parameter is itself not a perfect square, than -1 should be returned. You may assume the parameter is positive.

Examples:

findNextSquare(121) --> returns 144
findNextSquare(625) --> returns 676
findNextSquare(114) --> returns -1 since 114 is not a perfect

题解

Java的数学计算并没有内置到基本数据类型的成员函数中(否则int,long这类内置数据类型就没法参与运算了),而是集中到了Math包中。

将sq开方,并判断是否为整数,我的做法是把开方后的数强制转化为整形,然后平方检验。

import java.util.*;
import java.io.*;

class NumberFun {
  public static long findNextSquare(long sq) {
	  if (Math.pow((long)Math.sqrt(sq),2) != sq)
		  return -1;
      return (long)Math.pow(Math.sqrt(sq)+1,2);
  }
}

当然,标准答案告诉我并不需要这么复杂,Java本身浮点数是支持取模运算,而对1取模可以用来判断是否是整数——

public class NumberFun {
  public static long findNextSquare(long sq) {
      return Math.sqrt(sq) % 1 != 0 ? -1 : (long)Math.pow(Math.sqrt(sq)+1,2);
  }
}

 

Codewars Java练习:Bit Counting

题目

Write a function that takes an (unsigned) integer as input, and returns the number of bits that are equal to one in the binary representation of that number.

Example: The binary representation of 1234 is 10011010010, so the function should return 5 in this case

题解

我使用了每次右移,统计奇偶性的解法——

import java.util.*;
import java.io.*;

class BitCounting {

	public static int countBits(int n){
		int result = 0;
		while (n!=0) {
			if ((n&1) == 1) result ++;
			n >>= 1;
		}
		return result;
	}

}

标准解法中,我比较喜欢的有如下代码——

直接使用Integer的库函数

public class BitCounting {

  public static int countBits(int n){
    
    return Integer.bitCount(n);
  }
  
}

转换为字符串处理,其中用到了Java中的Lambda表达式

public class BitCounting {

  public static int countBits(int n){
    return (int) Integer.toBinaryString(n).chars()
              .filter(c -> c == '1')
              .count();
  }
  
}

 

 

Codewars Java练习:Two to One

题目名称

TwoToOne

题目

Take 2 strings s1 and s2 including only letters from ato z. Return a new sorted string, the longest possible, containing distinct letters,

  • each taken only once – coming from s1 or s2.

Examples:

a = “xyaabbbccccdefww” b = “xxxxyyyyabklmopq”

longest(a, b) -> “abcdefklmopqwxy”

a = “abcdefghijklmnopqrstuvwxyz”

longest(a, a) -> “abcdefghijklmnopqrstuvwxyz”

题目大意

给定两个字符串,将其加起来,去重,排序后输出。

题解

刻意练习了一下ArrayList类似的容器的使用方式,发现这类问题通常有两个核心要点——

  • 如何将原始元素类型转化为对象形式,比如本题中如何将char数组和Character数组相互转换——
    • 事实上,这个转换在后期的Java版本中有ArrayUtils类提供转换函数
    • 而在早起的版本中,只有通过for语句逐个元素构造
  • 如何在内置数组、ArrayList之间转化
  • 如何在可重ArrayList和不可重的HashSet之间转化。
import java.util.*;
import java.io.*;
class TwoToOne {
	public static String longest(String s1,String s2) {
		char[] arr = (s1+s2).toCharArray();
		Character[] arr_obj = new Character[arr.length];
		for (int i=0;i<arr.length;i++)
			arr_obj[i] = new Character(arr[i]);
		HashSet<Character> dist_set = new HashSet<Character>(new ArrayList<Character>(Arrays.asList(arr_obj)));
		ArrayList<Character> dist_arr = new ArrayList<Character>();
		dist_arr.clear();
		dist_arr.addAll(dist_set);
		Collections.sort(dist_arr);
		String result = new String();
		for (Character w:dist_arr)
			result += w;
		return result;
	}
};

class Main {
	public static void main(String[] args) {
		Scanner fin = new Scanner(System.in);
		String a,b;
		a = fin.next();
		b = fin.next();
		System.out.println(TwoToOne.longest(a,b));
	}
};

标准答案

最后欣赏一下标准答案——

public class TwoToOne {
    
    public static String longest (String s1, String s2) {
        String s = s1 + s2;
        return s.chars().distinct().sorted().collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();
    }
}

代码使用了String的chars()函数,返回了一个IntStream类,这个类支持了后续的所有的过滤变换操作。

Codewars Java练习:Consecutive strings

题目

You are given an array strarr of strings and an integer k. Your task is to return the first longest string consisting of k consecutive strings taken in the array.

#Example:

longest_consec([“zone”, “abigail”, “theta”, “form”, “libe”, “zas”, “theta”, “abigail”], 2) –> “abigailtheta”

n being the length of the string array, if n = 0 or k > n or k <= 0 return “”.

题解

算是中规中矩的一道题吧

import java.util.*;
import java.io.*;

class LongestConsec {

    public static String longestConsec(String[] ss, int k) {
		if (k < 0)
			k = 0;
		if (ss.length < k)
			return "";
		int len_arr[] = new int[ss.length+1];
		len_arr[0] = 0;
		for (int i=0;i<ss.length;i++)
			len_arr[i+1] = len_arr[i] + ss[i].length();
		int pos = -1, bst_ans = -1;
		for (int i=0;i+k-1<ss.length;i++) {
			if (len_arr[i+k] - len_arr[i] > bst_ans) {
				bst_ans = len_arr[i+k] - len_arr[i];
				pos = i+k-1;
			}
		}
		String result = new String();
		for (int i=pos-k+1;i<=pos;i++)
			result += ss[i];
		return result;
    }
};