算法刷题记录(LeetCode 390-420)

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 281,二者在计算机中二进制表示相同,差值为 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]=='.';
        
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值