13.机器人的运动范围
动态规划
联通性为什么要&& (dp[i - 1][j] || dp[i][j - 1]);
class Solution {
public int movingCount(int m, int n, int k) {
//状态:dp[i][j]代表第i,j个格子能否走到
boolean[][] dp = new boolean[m][n];
dp[0][0] = isValid(0, 0, k);
//转移方程
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(i == 0 && j == 0) continue;
else if(i == 0) dp[i][j] = isValid(i, j, k) && dp[i][j - 1];//0行边界横向查找
else if(j == 0) dp[i][j] = isValid(i, j, k) && dp[i - 1][j];//0列边界竖向查找
else dp[i][j] = isValid(i, j, k) && (dp[i - 1][j] || dp[i][j - 1]);//考虑连通性
}
}
int count = 0;//计算true的个数
for (boolean[] row : dp) {
for (boolean ele : row) {
if (ele) {
count++;
}
}
}
return count;
}
public boolean isValid(int i, int j, int k) {
int sum = 0;
while (i != 0) {
sum += i % 10;
i /= 10;
}
while (j != 0) {
sum += j % 10;
j /= 10;
}
return sum <= k;
}
}
14-I 剪绳子
数学问题,类比斐波拉契数列
class Solution {
public int cuttingRope(int n) {
if(n <= 3) return n - 1;
int a = n / 3, b = n % 3;
if(b == 0) return (int)Math.pow(3, a);
if(b == 1) return (int)Math.pow(3, a - 1) * 4;
return (int)Math.pow(3, a) * 2;
}
}
14-II剪绳子,考虑大数取模问题
class Solution {
public int cuttingRope(int n) {
//有大数取模问题
if(n <= 3) return n - 1;
int b = n % 3, p = 1000000007;
long rem =1,x=3;
for(int a = n / 3 - 1; a > 0; a /= 2) {
if(a % 2 == 1) rem = (rem * x) % p;
x = (x * x) % p;
}
if(b == 0) return (int)(rem * 3 % p);
if(b == 1) return (int)(rem * 4 % p);
return (int)(rem * 6 % p);//等价于3^(a-1)*3*2
}
}
15,二进制中1的个数
和>>>的区别
1、>> 表示右移,如果该数为正,则高位补0,若为负数,则高位补1。如:int i=15; i>>2的结果是3,移出的部分将被抛弃。
2、>>>表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0。
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while(n!=0){
res += n&1;
n >>>= 1; //表示无符号右移
}
return res;
}
}
16.数值的整数次方
class Solution {
public double myPow(double x, int n) {
if(x == 0) return 0;
double p=1.0 ;
long k = n;
if(k<0){
x = 1 / x;
k =-k;
}
while(k>0){
if((k & 1) == 1) p *=x;
x *=x;
k >>=1;
}
return p;
}
}
17.打印从1到最大的n位数
若n比较大,则比较耗内存
class Solution {
public int[] printNumbers(int n) {
int end = (int)Math.pow(10, n) - 1;
int[] res = new int[end];
for(int i = 0; i < end; i++)
res[i] = i + 1;
return res ;
}
}
18.删除链表的节点
直接遍历
/**
* 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 pre = head;
ListNode cur = head.next;
if(head == null) return null;
if(head.val == val) return head.next;
while(cur !=null && cur.val != val){
//超时
pre = cur;
cur = cur.next;
}
if(cur != null) pre.next = cur.next;//如果找到要删除的节点,节点指向操作
return head;
}
}
19,正则表达式匹配
调用match函数可以完成
底层实现有点困难,我还没看懂
20.表示数值的字符串(有难度)
罗列条件,创建查询表
class Solution {
public boolean isNumber(String s) {
//key存放类型,value状态
Map[] states = {
new HashMap<>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0. 起始空格 正负号 e 数字.
new HashMap<>() {{ put('d', 2); put('.', 4); }}, // 至少一位数字,后面跟着一个点 '.'
new HashMap<>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2. 数字.数字e空格
new HashMap<>() {{ put('d', 3); put('e', 5); put(' ', 8); }}, // 3.
new HashMap<>() {{ put('d', 3); }}, // 4.
new HashMap<>() {{ put('s', 6); put('d', 7); }}, // 5.
new HashMap<>() {{ put('d', 7); }}, // 6.
new HashMap<>() {{ put('d', 7); put(' ', 8); }}, // 7.
new HashMap<>() {{ put(' ', 8); }} // 8.若干空格
};
int p = 0;
char t;
for(char c : s.toCharArray()) {
if(c >= '0' && c <= '9') t = 'd';
else if(c == '+' || c == '-') t = 's';
else if(c == 'e' || c == 'E') t = 'e';
else if(c == '.' || c == ' ') t = c;
else t = '?';
if(!states[p].containsKey(t)) return false;
p = (int)states[p].get(t);
}
return p == 2 || p == 3 || p == 7 || p == 8;
}
}