leetcode443-475中的简单题
443. 字符串压缩
题目:
给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
思路:
设置两个标志,一个标识字母第一次出现的位置,另一个计算此字母出现的次数;用返回值作为char[]的索引并进行字母和数字的插入。
代码:
class Solution {
public int compress(char[] chars) {
int len = chars.length;
if(len<=1) return len;
int count = 0,i = 0,j = 1, cur = -1;
while(j<=len){
if(j!=len&&chars[i]==chars[j]){
count++;
j++;
}
if(j==len||chars[i]!=chars[j]){
chars[++cur] = chars[i];
if(cur+1<=len-1&&count!=0){
for(char c:((count+1)+"").toCharArray())
chars[++cur]=c;
}
i=j;
j++;
count=0;
}
}
return cur+1;
}
}
447. 回旋镖的数量
题目:
给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。
找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。
例子:
输入:
[[0,0],[1,0],[2,0]]
输出:
2
解释:
两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
思想:
没做出来,抄的。。
JAVA 实现: 这道题思路其实也比较简单,计算一点和其他点之间的距离,使用哈希表存储,若同一距离出现多次,则可以形成回旋镖。假设同一距离出现 n 次,由数字规律可推出回旋镖的数量 sum = n*(n-1) 。本人开始只能做到存储到哈希表,然后按该公式累加得到最后结果。参考了速度第一的答案,优化如下:假设当前同一距离的数量为 n, 回旋镖数量为 n*(n-1), 当再出现一个同一距离时,回旋镖的数量应为 (n+1)n,与之前相差 (n+1)n - n(n-1) = 2n, 所以只需要把最后答案加上 2*n, 最后 n+1 再存储到哈希表中。
代码:
class Solution {
public int numberOfBoomerangs(int[][] points) {
int len = points.length;
int ans = 0;
Map<Double,Integer> map = new HashMap<>();
for(int i = 0;i < len;i++){
for(int j = 0;j < len;j++){
if(i!=j){
double dis = Math.pow(points[i][0] - points[j][0],2)
+Math.pow(points[i][1] - points[j][1],2);
if(!map.containsKey(dis)){
map.put(dis,1);
}else{
int n = map.get(dis);
ans += 2*n;
map.put(dis,n + 1);
}
}
}
map.clear();
}
return ans;
}
}
448. 找到所有数组中消失的数字
题目:
给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
示例:
输入:
[4,3,2,7,8,2,3,1]
输出:
[5,6]
思路:
使用数组的下标来标记数字的出现于否,通过一遍遍历即可标记出全部已经出现的数组。
代码:
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> list = new ArrayList<>();
int len = nums.length;
for(int i =0;i<len;i++){
if(nums[Math.abs(nums[i]) - 1] > 0){
nums[Math.abs(nums[i]) - 1] = -nums[Math.abs(nums[i]) - 1];
}
}
for(int i=0;i<len;i++){
if(nums[i]>0) list.add(i+1);
}
return list;
}
}
453. 最小移动次数使数组元素相等
题目:
给定一个长度为n的数组,找出最少的移动次数使得数组中的所有元素都相等,一次操作为将数组中n-1各元素加1
思路:
移动次数等于所有元素和最小值相减的和。
代码:
class Solution {
public int minMoves(int[] nums) {
int len = nums.length;
int minNum = nums[0];
int result = 0;
for(int i=0;i<len;i++){
if(nums[i]<minNum) minNum = nums[i];
}
for(int i=0;i<len;i++){
if(nums[i]>minNum){
result += nums[i] - minNum;
}
}
return result;
}
}
455. 分发饼干
题目:
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj 。如果 sj >= gi ,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
思路:
对两个数组进行排序,通过一遍遍历得到结果。
代码:
class Solution {
public int minMoves(int[] nums) {
int len = nums.length;
int minNum = nums[0];
int result = 0;
for(int i=0;i<len;i++){
if(nums[i]<minNum) minNum = nums[i];
}
for(int i=0;i<len;i++){
if(nums[i]>minNum){
result += nums[i] - minNum;
}
}
return result;
}
}
459. 重复的子字符串
题目:
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
思路:
自己看代码吧,我写出来的太烂了,看看别人第一怎么写的。。。
代码:
class Solution {
public boolean repeatedSubstringPattern(String s) {
int[] primes = new int[]{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int l = s.length();
for (int i : primes) {
if (i > l) break;
if (l % i == 0) {
boolean valid = true;
int j = l / i;
for (int n = l; n > j; n -= j) {
if (!s.substring(n - j, n).equals(s.substring(n - 2 * j, n - j))) {
valid = false;
break;
}
}
if (valid) return true;
}
}
return false;
}
}//耗时0ms,速度无敌
461. 汉明距离
题目:
计算两个整数之间的汉明顿距离(长度在31位以内)
分析:
异或运算得出所有不同为1的位,每次进行向右或者向左移位相加就能得到。也可以参考一下java里是怎么实现汉明顿距离的。
代码:
class Solution {
public int hammingDistance(int x, int y) {
int z = x ^ y;
int sum = 0;
while (z!=0){
System.out.println(z&1);
sum += z & 1;
z = z>>1;
}
return sum;
}
}
463. 岛屿的周长
题目:
给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。
网格中的格子水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
思路:
递归求解;
或者双重for循环每次遇到值为1的方块就加一;同时判断当前方块右边相邻的是不是也是1,如果是就去掉他俩相邻的鞭(-2);同时判断当前方块下边相邻的是不是也是1,如果是就去掉他俩相邻的鞭(-2)。
代码:
class Solution {
public int islandPerimeter(int[][] grid) {
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
if(grid[i][j]==1)
return dfs(grid,i,j);
}
}
return 0;
}
int dfs(int[][] grid, int r, int c){
if(!(0<=r && r<grid.length && 0<=c && c<grid[0].length)) return 1;
if(grid[r][c]==0) return 1;
if(grid[r][c]!=1) return 0;
grid[r][c]=2;
return dfs(grid,r-1,c)+dfs(grid,r+1,c)+dfs(grid,r,c-1)+dfs(grid,r,c+1);
}
}
class Solution {
public int islandPerimeter(int[][] grid) {
if (grid == null || grid.length == 0) return 0;
int rows = grid.length;
int cols = grid[0].length;
int ones = 0;
int connects = 0;
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
if (grid[row][col] == 1) {
ones++;
if (col + 1 < cols && grid[row][col+1] == 1) connects++;
if (row + 1 < rows && grid[row+1][col] == 1) connects++;
}
}
}
return 4 * ones - 2 * connects;
}
}
475. 供暖器
题目:
冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
现在,给出位于一条水平线上的房屋和供暖器的位置,找到可以覆盖所有房屋的最小加热半径。
所以,你的输入将会是房屋和供暖器的位置。你将输出供暖器的最小加热半径。
说明:
给出的房屋和供暖器的数目是非负数且不会超过 25000。
给出的房屋和供暖器的位置均是非负数且不会超过10^9。
只要房屋位于供暖器的半径内(包括在边缘上),它就可以得到供暖。
所有供暖器都遵循你的半径标准,加热的半径也一样。
示例 1:
输入: [1,2,3],[2]
输出: 1
解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。
思路:
对于每个房屋,要么用前面的暖气,要么用后面的,二者取近的,得到距离;
对于所有的房屋,选择最大的上述距离。
代码:
class Solution {
public int findRadius(int[] houses, int[] heaters) {
Arrays.sort(houses);
Arrays.sort(heaters);
int heaterLen = heaters.length;
int pos = 0;
int res = 0;
for(int house : houses){
while(pos+1<heaterLen&&heaters[pos]<house){
pos++;
}
if(pos==0){
res = Math.max(res,Math.abs(heaters[pos] - house));
}else{
res = Math.max(res,Math.min(Math.abs(heaters[pos-1]-house),Math.abs(heaters[pos]-house)));
}
}
return res;
}
}
476. 数字的补数
题目:
给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。
思路:
获取一个和输入相同长度的最大数字,再进行异或运算就可。
代码:
class Solution {
public int findComplement(int num) {
int temp = num,c = 0;
while(temp>0){
temp >>= 1;
c = (c<<1) + 1;
}
return num^c;
}
}