392. Is Subsequence
bool isSubsequence(string s, string t) {
int pt1=0,pt2=0;
if (s.size()>t.size()){
return false;
}
while (pt2!=t.size()){
if (pt1==s.size()){
return true;
}
if (s[pt1]==t[pt2]){
pt1++;
}
pt2++;
}
return pt1==s.size();
}
393. UTF-8 Validation
class Solution {
static final int SECTION_A=128;
static final int SECTION_B=192;
static final int SECTION_C=224;
static final int SECTION_D=240;
static final int SECTION_E=248;
public boolean validUtf8(int[] data) {
int i=0;
while (i<data.length){
if (data[i]<SECTION_A){
i++;
continue;
}
else if (data[i]<SECTION_B){
return false;
}
else if (data[i]>=SECTION_E){
return false;
}
else if (data[i]>=SECTION_D){
if (i+3>= data.length){
return false;
}
i++;
int j=i+2;
for (;i<=j;i++){
if (data[i]<SECTION_A||data[i]>=SECTION_B){
return false;
}
}
}
else if(data[i]>=SECTION_C){
if (i+2>= data.length){
return false;
}
i++;
int j=i+1;
for (;i<=j;i++){
if (data[i]<SECTION_A||data[i]>=SECTION_B){
return false;
}
}
}
else{
if (i+1>= data.length){
return false;
}
i++;
if (data[i]<SECTION_A||data[i]>=SECTION_B){
return false;
}
i++;
}
}
return true;
}
}
394. Decode String
有问题,未考虑不在括号内的元素
public static String decodeString(String s) {
StringBuilder builder=new StringBuilder();
Stack<Character> operations=new Stack<>();
int parenthesis=0;
int i=0;
String tempString;
String multiplier="";
while(i<s.length()){
if(s.charAt(i)!=']'){
if(s.charAt(i)=='['){
parenthesis++;
}
operations.push(s.charAt(i));
}
else{
tempString="";
while(parenthesis==0&&!operations.isEmpty()&&!Character.isDigit(operations.peek())){
tempString=operations.pop()+tempString;
}
while(parenthesis>0){
multiplier="";
while(operations.peek()!='['){
tempString=operations.pop()+tempString;
}
operations.pop();
parenthesis--;
while(!operations.isEmpty()&& Character.isDigit(operations.peek())){
multiplier=operations.pop()+multiplier;
}
tempString=tempString.repeat(Integer.parseInt(multiplier));
}
builder.append(tempString);
}
i++;
}
tempString="";
while(!operations.isEmpty()){
tempString=operations.pop()+tempString;
}
builder.append(tempString);
return builder.toString();
}
396. Rotate Function
int maxRotateFunction(vector<int>& nums) {
int sum=0;
int arr_sum=0;
int n=nums.size();
for (int val:nums) {
arr_sum+=val;
}
for (int i = 0; i < nums.size(); ++i) {
sum+=i*nums[i];
}
int max_val=sum;
for (int i=1;i<n;i++) {
sum= sum+arr_sum-n*nums[n-i];
max_val=max(max_val,sum);
}
return max_val;
}
397. Integer Replacement
int bfs(int num,int ops){
if (num==1){
return ops;
}
if (num%2==0){
return bfs(num/2,ops+1);
}
return min(bfs(num+1,ops+1), bfs(num-1,ops+1));
}
int integerReplacement(int n) {
if (n == numeric_limits<int>::max()) {
return 32;
}
return bfs(n,0);
}
*399. Evaluate Division
class Solution {
static class Pair{
String from;
String to;
public Pair(String from, String to) {
this.from = from;
this.to = to;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Pair)) {
return false;
}
Pair pair = (Pair) obj;
return Objects.equals(from, pair.from) && Objects.equals(to, pair.to);
}
@Override
public int hashCode() {
return Objects.hash(from, to);
}
}
static class Node{
String from;
HashMap<String,Double> to=new HashMap<>();
public Node(String from) {
this.from = from;
}
}
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
HashMap<String,Node> nodes=new HashMap<>();
for (int i=0;i<equations.size();i++){
String valFrom=equations.get(i).get(0);
String valTo=equations.get(i).get(1);
if (!nodes.containsKey(valFrom)){
nodes.put(valFrom,new Node(valFrom));
}
if (!nodes.containsKey(valTo)){
nodes.put(valTo,new Node(valTo));
}
Node from = nodes.get(valFrom);
from.to.put(valTo,values[i]);
Node to =nodes.get(valTo);
to.to.put(valFrom,1/values[i]);
}
HashSet<Pair> visited=new HashSet<>();
ArrayList<Double> ans=new ArrayList<>();
for (var q:queries){
visited.clear();
ans.add(calculate(q.get(0),q.get(1),nodes,1.0,"N/A",visited));
}
return ans.stream().mapToDouble(i->i).toArray();
}
public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {
HashMap<String,Node> nodes=new HashMap<>();
for (int i=0;i<equations.length;i++){
String valFrom=equations[i][0];
String valTo=equations[i][1];
if (!nodes.containsKey(valFrom)){
nodes.put(valFrom,new Node(valFrom));
}
if (!nodes.containsKey(valTo)){
nodes.put(valTo,new Node(valTo));
}
Node from = nodes.get(valFrom);
from.to.put(valTo,values[i]);
Node to =nodes.get(valTo);
to.to.put(valFrom,1/values[i]);
}
ArrayList<Double> ans=new ArrayList<>();
HashSet<Pair> visited=new HashSet<>();
for (var q:queries){
visited.clear();
ans.add(calculate(q[0],q[1],nodes,1.0,"N/A",visited));
}
return ans.stream().mapToDouble(i->i).toArray();
}
public double calculate(String src,String target,HashMap<String,Node> nodes,double prevVal,String parent,HashSet<Pair> visited){
if ((!nodes.containsKey(src))||(!nodes.containsKey(target))){
return -1;
}
if (visited.contains(new Pair(parent,src))){
return -1;
}
visited.add(new Pair(parent,src));
if (src.equals(target)){
return prevVal*1;
}
if (nodes.get(src).to.containsKey(target)){
return nodes.get(src).to.get(target)*prevVal;
}
else{
for (var node:nodes.get(src).to.keySet()) {
if (node.equals(parent)){
continue;
}
double val =calculate(node, target, nodes,prevVal*nodes.get(src).to.get(node),src,visited);
if (val!=-1){
return val;
}
// visited.remove(new Pair(src,node));
}
}
return -1;
}
}
400. Nth Digit
public int findNthDigit(int n){
if (n < 10) {
return n;
}
int power=1;
long curr=9;
long scope=9;
long prev=-1;
long currScope=9;
while (scope<n){
power+=1;
curr=curr*10;
currScope=curr*power;
prev=scope;
scope+=currScope;
}
long currInt= (long) (Math.pow(10,power-1)-1);
System.out.println(currInt);
long residual=n-prev;
currInt=currInt+residual/power;
long digit=residual%power;
if (digit==0){
String res=String.valueOf(currInt);
return Character.getNumericValue(res.charAt(res.length()-1));
}
else{
currInt++;
String res=String.valueOf(currInt);
return Character.getNumericValue(res.charAt((int) (digit-1)));
}
}
标准解法
public String decodeString(String s) {
//双栈解法:
//准备两个栈:一个存放数字,一个存放字符串
//遍历字符有四种情况
//1、如果是数字 将数字转成整型数字等待处理
//2、如果是字符 将字符添加到当前临时字符串中
//3、如果是'[' 将当前数字和临时字符串添加到各自栈中
//4、如果是']' 将数字和字符栈各取出,然后拼接成新的临时字符串
//Java 推荐用Deque ArrayDeque实现栈
//创建数字栈,创建字符串栈 及临时数字和临时字符串
Deque<Integer> stack_digit = new ArrayDeque<>();
Deque<StringBuilder> stack_string = new ArrayDeque<>();
int tNum = 0;
StringBuilder tString = new StringBuilder();
int i = 0;
//遍历字符串 分4中情况
while(i<s.length()){
char ch = s.charAt(i++);
if(ch == '['){ //如果是"[" 将临时数字和临时字符串入栈
stack_digit.push(tNum);
stack_string.push(tString);
tNum = 0;
tString = new StringBuilder();
}else if(ch == ']'){ //如果是"]" 将数字和字符串出栈 此时临时字符串res = 出栈字符串 + 出栈数字*res
StringBuilder temp = stack_string.pop();
int count = stack_digit.pop();
for(int j = 0;j < count;j++){
temp.append(tString.toString());
}
tString = temp;
}else if('0' <= ch && ch <= '9'){
//如果是数字 将字符转成整型数字 ch-‘0’。 注意数字不一定是个位 比如100[a] 所以digit要*10
tNum = tNum * 10 + ch - '0';
}else{
//如果是字符 直接将字符放在临时字符串中
tString.append(ch);
}
}
return tString.toString();
}
402. Remove K Digits
Monotonic Stack
public String removeKdigits(String num, int k) {
if(k>=num.length()){
return "0";
}
Deque<Character> digits =new LinkedList<>();
for (int i=0;i<num.length();i++){
while (k>0&&!digits.isEmpty()&&digits.peekLast()>num.charAt(i)){
digits.removeLast();
k--;
}
digits.addLast(num.charAt(i));
}
String res = Arrays.stream(digits.toArray()).map(String::valueOf) .collect(Collectors.joining());
res=res.substring(0,res.length()-k);
res=res.replaceAll("^0+(?!$)","");
return res;
}
*403. Frog Jump
直接DFS 超时
带有记忆
class Solution {
public:
unordered_map<int,int> stoneMap;
set<pair<int,int>> cache;
bool canCross(vector<int>& stones) {
for(int i=0;i<stones.size();i++){
stoneMap[stones[i]]=i;
}
return dfs(0,1,stones);
}
bool dfs(int currIdx,int currJump,vector<int>& stones){
if (currJump<=0){
return false;
}
if (!stoneMap.count(stones[currIdx]+currJump)){
return false;
}
if (cache.count(make_pair(currIdx,currJump))){
return false;
}
cache.insert(make_pair(currIdx,currJump));
if (stoneMap[stones[currIdx]+currJump]==stones.size()-1){
return true;
}
int newIdx=stoneMap[stones[currIdx]+currJump];
return dfs(newIdx,currJump+1,stones)||dfs(newIdx,currJump,stones)||dfs(newIdx,currJump-1,stones);
}
};
DP
bool canCross(vector<int>& stones) {
if (stones[1]!=1){
return false;
}
vector<vector<bool>> cache(stones.size(), vector<bool>(stones.size()+1, false));
cache[1][1]=true;
cache[0][0]=true;
for(int i=2;i<stones.size();i++){
for (int j = 0; j < i; ++j) {
int k = stones[i] - stones[j];
if (j+1>=k){
cache[i][k]= cache[j][k - 1] || cache[j][k] || cache[j][k + 1];
}
}
}
for (int i = 1; i < stones.size(); ++i) {
if(cache[stones.size() - 1][i]) return true;
}
return false;
}
404. Sum of Left Leaves
public int sumOfLeftLeaves(TreeNode root) {
if (root == null) {
return 0;
}
int currLeaves = 0;
if (root.left != null) {
if (root.left.left == null && root.left.right == null) {
currLeaves += root.left.val;
} else {
currLeaves += sumOfLeftLeaves(root.left);
}
}
currLeaves += sumOfLeftLeaves(root.right);
return currLeaves;
}
*405. Convert a Number to Hexadecimal
补码的转换
CSAPP第一章有介绍2’s Comp. -> Unsigned,也就是用Unsigned的大正数表示Signed负数。举个例子,8位int中-1表示为0b11111111(T),无符号整数0b11111111(U)表示为 2 8 − 1 2^8 - 1 28−1,二者在计算机中二进制表示相同,差值为 2 8 2^8 28。因此先在负数的基础上加上 2 8 2^8 28即可转化为一个大正数,二者的二进制表示相同。在这里32位整形则将原始负数num加上 2 3 2 2^32 232先转换成大正数,以无符号整形表示。该无符号整形与原始有符号负数的2进制标是是一样的。
string toHex(int _num) {
if (_num==0){
return "0";
}
long num=_num;
if (num<0){
num+= (long)pow(2,32);
}
string hexDetonation;
while (num>0){
int val=num%16;
if (val<=9){
char ch=val+'0';
hexDetonation.append(1,ch);
}
else{
char ch=val-10+'a';
hexDetonation.append(1,ch);
}
num/=16;
}
reverse(hexDetonation.begin(), hexDetonation.end());
return hexDetonation;
}
*406. Queue Reconstruction by Height
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(),[](vector<int> a,vector<int> b){
if (a[0]==b[0]){
return a[1]<b[1];
}
return a[0]>b[0];
});
vector<vector<int>> res;
res.push_back(people[0]);
for (int i = 1; i < people.size(); ++i) {
if (people[i][1]==res.size()){
res.push_back(people[i]);
}
else{
res.insert(res.begin()+people[i][1],people[i]);
}
}
return res;
}
409. Longest Palindrome
int longestPalindrome(string s) {
int arr[128];
fill(arr,arr+128,0);
for (char ch:s) {
arr[ch]++;
}
int res=0;
for (int val:arr) {
res+=val/2*2;
}
for (int val:arr) {
if (val%2){
return res+1;
}
}
return res;
}
412. Fizz Buzz
vector<string> fizzBuzz(int n) {
vector<string> ans(n);
for (int i = 0; i < n; ++i) {
if ((i+1)%15==0){
ans[i]="FizzBuzz";
continue;
}
if ((i+1)%3==0){
ans[i]="Fizz";
continue;
}
if ((i+1)%5==0){
ans[i]="Buzz";
continue;
}
ans[i]=to_string(i+1);
}
return ans;
}
413. Arithmetic Slices
int numberOfArithmeticSlices(vector<int>& nums) {
if (nums.size()<2){
return 0;
}
int right=1;
int left=0;
int gap=nums[right]-nums[left];
right++;
int ways=0;
while (right<nums.size()){
if (nums[right]-nums[right-1]!=gap){
gap=nums[right]-nums[right-1];
if (right-left>=2){
int calculateLimit=right-left-2;
ways+=(1+calculateLimit)*(calculateLimit)/2;
}
left=right-1;
}
right++;
}
if (right-left>=2){
int calculateLimit=right-left-2;
ways+=(1+calculateLimit)*(calculateLimit)/2;
}
return ways;
}
414. Third Maximum Number
public int thirdMax(int[] nums) {
TreeSet<Long> set=new TreeSet<>((a,b)-> -Long.compare(a,b));
for (long val:nums){
set.add((long) val);
}
if (set.size()<3){
return (int)set.first().intValue();
}
for (int i=0;i<2;i++){
set.pollFirst();
}
return (int)set.first().intValue();
}
*416. Partition Equal Subset Sum
public boolean canPartition(int[] nums) {
int sum=Arrays.stream(nums).sum();
if (sum%2!=0){
return false;
}
int target=sum/2;
boolean[][] dp=new boolean[nums.length+1][target+1];
for(int i=0;i<=nums.length;i++){
dp[i][0]=true;
}
for (int i=1;i<=nums.length;i++){
for (int j=1;j<=target;j++){
if (j>=nums[i-1]){
dp[i][j]|=dp[i-1][j-nums[i-1]]|dp[i-1][j];
}
else{
dp[i][j]=dp[i-1][j];
}
}
}
return dp[nums.length][target];
}
*419. Battleships in a Board
数数方法
确定每一个都是战舰的头部
class Solution {
public:
int countBattleships(vector<vector<char>>& board) {
int ans=0;
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
if (board[i][j]=='X'&&isHead(i,j,board)) ans++;
}
}
return ans;
}
bool isHead(int i,int j,vector<vector<char>>& board){
if (i==0&&j==0){
return true;
}
if (i!=0&&j!=0){
return board[i-1][j]=='.'&&board[i][j-1]=='.';
}
if (i!=0){
return board[i-1][j]=='.';
}
return board[i][j-1]=='.';
}
};