Difficulty: 中等
地上有一个m行n列的方格,从坐标 [0,0]
到坐标 [m-1,n-1]
。一个机器人从坐标 [0, 0]
的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?
示例 1:
输入:m = 2, n = 3, k = 1
输出:3
示例 2:
输入:m = 3, n = 1, k = 0
输出:1
提示:
1 <= n,m <= 100
0 <= k <= 20
//关键点:机器人要一步一步的走
//被挡住的地方即使数位和小于k也是过不去的
class Solution {
public int movingCount(int m, int n, int k) {
boolean[][] used = new boolean[m][n];
return getCount(m, n, 0, 0, k, used);
}
public int getCount(int m, int n, int i, int j, int k, boolean[][] used){
int count = 0;
if(i<0 || i>=m || j<0 || j>=n || used[i][j] || getSum(i)+getSum(j)>k){
return 0;
}
count++;
used[i][j] = true;
count += getCount(m, n, i-1, j, k, used); //四个方向
count += getCount(m, n, i, j-1, k, used);
count += getCount(m, n, i+1, j, k, used);
count += getCount(m, n, i, j+1, k, used);
return count;
}
public int getSum(int i){
int sum = 0;
while(i != 0){
sum += i%10;
i = i/10;
}
return sum;
}
}
Difficulty: 中等
给你一根长度为 n
的绳子,请把绳子剪成整数长度的 m
段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1]
。请问 k[0]*k[1]*...*k[m-1]
可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
提示:
2 <= n <= 58
注意:本题与主站 343 题相同:
// 方法一:暴力解法
//class Solution {
// public int cuttingRope(int n) {
// int max = 0;
// for(int i=2; i<=n; i++){ //分成几段
// int x = n/i, y = n%i;
// int sum = 1;
// for(int j=0; j
// if(y > 0){
// sum *= (x+1);
// y--;
// }
// else sum *= x;
// }
// max = Math.max(max, sum);
// }
// return max;
// }
// }
//方法二:规律:当n大于3的时候,优先选3;
//当n=1的时候,挪出一个3 ,凑成4;
//当n=2的时候,直接乘以2
class Solution{
public int cuttingRope(int n) {
if(n == 2) return 1;
if(n == 3) return 2; //m>1,所以只能分成2和1
if(n == 4) return 4;
int sum = 1;
while(n > 4){
sum *= 3;
n -= 3;
}
return sum*n;
}
}
Difficulty: 中等
给你一根长度为 n
的绳子,请把绳子剪成整数长度的 m
段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m - 1]
。请问 k[0]*k[1]*...*k[m - 1]
可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
提示:
2 <= n <= 1000
注意:本题与主站 343 题相同:
//关键点:使用上一题的规律,而且要将sum定义成long
class Solution {
public int cuttingRope(int n) {
if(n == 2) return 1;
if(n == 3) return 2;
if(n == 4) return 4;
long sum = 1;
while(n > 4){
sum = sum*3%1000000007;
n = n-3;
}
return (int)(sum*n%1000000007);
}
}
Difficulty: 简单
请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。
注意:本题与主站 191 题相同:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int count = 0;
while(n != 0){ //(1)不能写n>0,因为负数的二进制也有1
count = count + (n&1); // (2)加号的优先级比与运算高,一定要加括号
n = n>>>1; //(3)有符号右移>>>,无符号右移>>
}
return count;
}
}
Difficulty: 中等
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
示例 1:
输入: 2.00000, 10
输出: 1024.00000
示例 2:
输入: 2.10000, 3
输出: 9.26100
示例 3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:
注意:本题与主站 50 题相同:
/*
快速幂解法:
(1)当n为偶数, pow(x, n) = pow(x, n/2) * pow(x, n/2);
(2)当n为奇数, pow(x, n) = pow(x, n/2) * pow(x, n/2) * x;
初始化条件:
(1)if(n == 0) return 1;
(2)if(n == 1) return x;
(3)if(n == -1) return 1/x;
*/
class Solution {
public double myPow(double x, int n) {
if(n == 0) return 1;
if(n == 1) return x;
if(n == -1) return 1/x;
double half = myPow(x, n/2);
double pow = myPow(x, n%2);
return half*half*pow;
}
}
Difficulty: 简单
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
**注意:**此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
说明:
free
或 delete
被删除的节点/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
ListNode flag = new ListNode(-1), node;
flag.next = head;
node = flag;
while(node!=null && node.next!=null && node.next.val!=val){
node = node.next;
}
node.next = node.next.next;
return flag.next;
}
}
Difficulty: 困难
请实现一个函数用来匹配包含'. '
和'*'
的正则表达式。模式中的字符'.'
表示任意一个字符,而'*'
表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"
与模式"a.a"
和"ab*ac*a"
匹配,但与"aa.a"
和"ab*a"
均不匹配。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "a*"
输出: true
解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
示例 3:
输入:
s = "ab"
p = ".*"
输出: true
解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
示例 4:
输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
示例 5:
输入:
s = "mississippi"
p = "mis*is*p*."
输出: false
s
可能为空,且只包含从 a-z
的小写字母。p
可能为空,且只包含从 a-z
的小写字母以及字符 .
和 *
,无连续的 '*'
。注意:本题与主站 10 题相同:
class Solution {
public boolean isMatch(String s, String p) {
char[] str = s.toCharArray();
char[] ptr = p.toCharArray();
return help(str, ptr, 0, 0);
}
public boolean help(char[] str, char[] ptr, int i, int j){
int len1 = str.length, len2 = ptr.length;
if(j == len2) return i==len1;
if(i == len1){
if(j == len2-1) return false; //只剩下一个
if(ptr[j+1] != '*') return false;
return help(str, ptr, i, j+2);
}
if(str[i]==ptr[j] || ptr[j]=='.'){ //相等
if(j+1<len2 && ptr[j+1]=='*'){
return help(str, ptr, i, j+2) || //匹配0次
help(str, ptr, i+1, j+2) || //匹配1次
help(str, ptr, i+1, j); //匹配多次
}
else{
return help(str, ptr, i+1, j+1);
}
}
else{ //不相等
if(j+1<len2 && ptr[j+1]=='*'){ //匹配0次
return help(str, ptr, i, j+2);
}
else return false;
}
}
}
Difficulty: 简单
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10000
class Solution {
public int[] exchange(int[] nums) {
int len = nums.length;
int l = 0, r = len-1;
while(l < r){
while(l<r && nums[l]%2 != 0) l++;
while(l<r && nums[r]%2 == 0) r--;
if(l < r){
int temp = nums[l];
nums[l] = nums[r];
nums[r] = temp;
}
}
return nums;
}
}
Difficulty: 简单
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode slow = head, fast = head;
for(int i=0; i<k; i++){
if(fast == null) return null;
fast = fast.next;
}
while(fast != null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
Difficulty: 简单
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
注意:本题与主站 206 题相同:
注意:递归写法,可以模拟一下过程,就知道要怎么写了
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null || head.next==null) return head;
ListNode node = reverseList(head.next);
head.next.next = head; //不能写成 node.next = head, 因为node是头结点
head.next = null;
return node;
}
}