Git Product home page Git Product logo

-'s Introduction

代码随想录刷题日记(按照专题刷)

第六章 字符串

6.2 反转字符串

--0321打卡:解题Issue #8

6.3 反转字符串II

--0321打卡:解题Issue #9

6.4 反转字符串里的单词

--0321打卡:解题Issue #10

第十一章 动态规划

(一)方法论总结

1、遍历顺序
先物品还是先容量?

先物品的情况:无序组合问题、01背包问题 先容量的情况:有序排列问题、完全背包问题

前向后还是后向前?

前向后的情况:依赖于前一项or前几项做出决策的问题 后向前的情况:滚动数组,覆盖式更新

2、初始值
dp[0]为0还是1?

dp[0]为0的情况:通常是最小凑数问题,需要逐个累加 dp[0]为1的情况:通常是组合问题,需要各个情况考虑到

其他值为0/INT_MAX/INT_MIN?

0的情况:通常是递推方程为非最大最小的相加/相减,即无最优情况 INT_MAX/INT_MIN:通常是递推方程含有最优求解

(二)刷题笔记

11.8 不同的二叉搜索树

--0320打卡:解题Issue #1

1.9 0-1背包理论基础

1.10 分割等和子集

--0320打卡:解题Issue #2

1.11 目标和

--0320打卡:解题Issue #3

11.12 一和零

11.13 完全背包理论基础

11.14 零钱兑换I

--0321打卡:解题Issue #5

11.15 拼凑出一个正整数

--0321打卡:解题Issue #6

11.16 多步爬楼梯

11.17 零钱兑换II

--0321打卡:解题Issue #4

1.18 完全平方数

--0321打卡:解题Issue #7

1.19 单词拆分

1.20 买卖股票的最佳时机

--0322打卡:解题Issue #11

1.21 买卖股票的最佳时机II

--0322打卡:解题Issue #12

1.22 买卖股票的最佳时机III

--0322打卡:解题Issue #13

1.23 买卖股票的最佳时机IV

1.24 最佳买卖股票时机(含冷冻期)

-'s People

Contributors

liyueying233 avatar

Watchers

 avatar

-'s Issues

11.11 目标和(leetcode494)

【题目】微软一面原题
image
【思路】

  • 解法一:回溯法
  1. 建立backtrack函数,参数为开始节点start、目标值、数组;全局函数为实时sum记录、path、ans
  2. 递归出口:当start增长到nums.size()时,若sum与target相等加入ans并退出
  3. 单层搜索逻辑
    循环-1、1
    夹心面包结构
  • 解法二:动态规划法
  1. 建立dp[i][j]数组代表第0~i个商品可选择,达到和为j-sum,要么放入,要么扣除,计算方法总数
  2. 初始值:只计算当放入第0个商品时的情况,注意坑点--nums[0]=0,此时总数为2,反之为1
  3. 建立dp递推公式:dp[i][j]=dp[i-1][j-n[i]+dp[i-1][j+n[i]]注意范围不要越界(提前进行0~2s+1的判断)
  4. 确定遍历顺序:顺向遍历
  5. 打印dp数组

【代码】

  • 解法一:回溯法--特别注意各个参数的含义(leetcode超时)
class Solution {
public:
    vector<int>path;
    vector<vector<int>>ans;
    int sum;
    void backtrack(int start,vector<int>&nums,int target){
        //递归出口--收集结果
        if(start == nums.size()){
            if(sum==target){
                ans.push_back(path);   
            }
            return;
        }
        int a[2]={1,-1};
        //单层递归逻辑
        for(int i=0;i<=1;i++){
            path.push_back(a[i]);
            sum+=a[i]*nums[start];
            backtrack(start+1,nums,target);
            sum-=a[i]*nums[start];
            path.pop_back();
        }
    }

    int findTargetSumWays(vector<int>& nums, int target) {
        backtrack(0,nums,target);
        return ans.size();
    }
};
  • 解法二:动态规划--类比背包问题
class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
       //本题可类比背包问题
       int sum=0;
        for(int i=0;i<nums.size();i++){
            sum+=nums[i];
        }
        //边界条件 绝对值范围超过了sum的绝对值范围则无法得到
        if (abs(target) > abs(sum)) return 0;

       //1确定dp数组下标含义
       vector<vector<int>>dp(nums.size(),vector<int>(2*sum+1,0));
       //2初始化第一行数据
        if (nums[0] == 0) {//为0可加可减
            dp[0][sum] = 2;
        } else {//仅有一种情况,以sum为中心点
            dp[0][sum + nums[0]] = 1;
            dp[0][sum - nums[0]] = 1;
        }
       //4遍历顺序
       for(int i=1;i<nums.size();i++){
           for(int j=0;j<2*sum+1;j++){
            //    //3递推公式
                int r = (j+nums[i]>2*sum?0:j+nums[i]);
                int l = (j-nums[i]<0?0:j-nums[i]);
                dp[i][j]=dp[i-1][r]+dp[i-1][l];
           }
       }
       //5打印输出
        for(int i=0;i<nums.size();i++){
           for(int j=0;j<2*sum+1;j++){
               cout<<dp[i][j]<<" ";
           }
           cout<<endl;
       }
       return dp[nums.size()-1][sum+target];
    }
};

11.14 零钱兑换(leetcode518)

【题目】
image
【思路】

  • 要求当前状态的种类数,需要联想到上一状态,即硬币加入前后的情况
  • 由于是种类数之和因此需要将每种情况加和
  • 按照代码随想录,代码步骤如下:
  1. 确定dp数组下标及含义:dp[i]表示凑齐钱币数为i共有多少种方案
  2. 确定初始值:dp[0]=1!!!
  3. 确定递推方程:dp[i]+=dp[i-coins[j]]
  4. 确定遍历顺序:外层是钱币种类,内层才是钱币数,否则会出现重复情况
  5. 打印DP数组

【代码】

class Solution {
public:
    int change(int amount, vector<int>& coins) {
        //1确定dp数组下标及含义:dp[i]表示凑齐i元的种类数
        vector<int>dp(amount+1,0);
        //2初始值:dp[0]=0其他都为0
        dp[0]=1;
        // for(int j=0;j<coins.size();j++){
        //     dp[coins[j]]=1;
        // }
        for(int j=0;j<coins.size();j++){
            for(int i=coins[j];i<=amount;i++){
                //3递推公式:dp[i]+=dp[i-coins[j]]
                dp[i]+=dp[i-coins[j]];
            }
        }
        //4遍历顺序:外层是钱币种类数,内层是种类数(特别注意:如果反过来将会形成排列数)
        //5打印DP数组
        for(int i=0;i<=amount;i++){
            cout<<dp[i]<<" ";
        }
        return dp[amount];
    }
};

6.2 翻转字符串(leetcode344)

【题目】
image
【思路】

  • 方法:双指针
  • 定义左右俩指针从尽头出发,向中间靠拢
  • 每次调换左右指针处的元素值

【代码】

class Solution {
public:
    void reverseString(vector<char>& s) {
        int i=0;
        int j=s.size()-1;
        while(i<j){
            swap(s[i],s[j]);
            i++;j--;
        }
        return;
    }
};

11.15 拼凑出一个正整数

【题目】
image
【思路】

  • 由于本题要求顺序不同,求种类数和
  • 需要先对target遍历然后再对nums遍历,从而确保顺序不同
  • 按照组合问题建立递推式
  • 代码步骤参照代码随想录,如下:
  1. 确定DP数组下标及含义:dp[i]表示凑齐i的组合数
  2. 初始化Dp数组:dp[0]=1,表示凑齐0的话只有一种选择(啥也不做)
  3. 建立递推公式:dp[i]+=dp[i-nums[j]]
  4. 确定遍历顺序:外层--钱币数,内层--nums种类
  5. 打印DP数组
    注意:遍历顺序如果先遍历target出来有顺序,如果先遍历种类数出来无顺序

【代码】

class Solution {
public:
    int combinationSum4(vector<int>& nums, int target) {
        //顺序不同的序列被视作不同的组合。有序组合--排列问题
        //1确定DP数组下标及含义:dp[i]表示凑齐i的组合数
        vector<int>dp(target+1,0);
        //2初始化Dp数组:dp[0]=1
        dp[0]=1;
        //3建立递推公式:dp[i]+=dp[i-nums[j]]
        for(int j=1;j<=target;j++){
            
            for(int i=0;i<nums.size();i++){
                //C++测试用例有两个数相加超过int的数据,所以需要在if里加上dp[i] < INT_MAX - dp[i - num]。
                if(j>=nums[i] && dp[j] < INT_MAX - dp[j - nums[i]]) 
                    dp[j] += dp[j-nums[i]];
            }
        }
        //4确定遍历顺序:外层--钱币数,内层--nums种类
        //5打印DP数组
        for(int i=0;i<=target;i++){
            cout<<dp[i]<<" ";
        }
        return dp[target];

    }
};

11.8 不同的二叉搜索树(leetcode96)

【题目】
image

【思路】

  • 分析:不难发现,当n=3时,根节点为1和3的子树与n=2时的树形态相同,而当n=1时,根节点为2的子树与n=1时的树形态相同。
  • 递推公式:dp[i]=∑dp[j-1]dp[i-j];(例如dp[3]=dp[0]*dp[2]+dp[1]*dp[1]+dp[2]*dp[0])
  • 代码步骤(参考卡哥递归五部曲)
  1. 确定递推数组下标含义:dp[i]代表根节点为i的搜索树数量
  2. 数组初始化为1
  3. 确定递推公式dp[i]=∑dp[j-1]dp[i-j],其中j∈[1,i];
  4. 确定遍历顺序由于依托于小于i的dp值,因此从小到大遍历
  5. 打印dp检查情况

【代码】

class Solution {
public:
    //1确定dp数组,i表示节点数量为i的二叉搜索树种数
    int numTrees(int n) {
        //2dp数组初始化
        int dp[20]={1};
        //4遍历顺序
        for(int i=0;i<=n;i++){
            for(int j=1;j<=i;j++){
                //3递推公式
                dp[i] += dp[j-1]*dp[i-j];    
            }            
        }
        //5打印dp数组
        for(int i=0;i<=n;i++){
            cout<<dp[i]<<" ";
        }
        return dp[n];        
    }
};

11.18 完全平方数(leetcode279)

【题目】
image
【思路】

  • 本题需要求最小数量的完全平方数之和以凑齐目标数n
  • 实际上为最小硬币题中,将硬币面值全换为了平方数
  • 参考代码随想录,代码步骤如下:
  1. 构造平方数组
  2. 确定dp数组下标及含义:dp[i]凑齐i需要的最少数量
  3. 初始化dp数组:dp[0]=0,其他为INT_MAX
  4. 确定状态转移方程:dp[i]=min(dp[i],dp[i-n[j]])
  5. 确定遍历顺序:先进行整数的遍历,再进行平方数遍历
  6. 打印DP数组

【代码】

class Solution {
public:
    int numSquares(int n) {
        //0构造平方数组
        int m = sqrt(n);
        vector<int>nums(m);
        for(int i=0;i<m;i++){
            nums[i] = (i+1)*(i+1);
        }
        //1确定dp数组下标及含义:dp[i]凑齐i需要的最少数量
        vector<int>dp(n+1,INT_MAX);
        //2初始化dp数组:dp[0]=0,其他为INT_MAX
        dp[0]=0;
        //3确定状态转移方程:dp[i]=min(dp[i],dp[i-n[j]])
        for(int i=0;i<=n;i++){
            for(int j=0;j<m;j++){
                if(i>=nums[j])dp[i]=min(dp[i],dp[i-nums[j]]+1);
            }
        }
        //4确定遍历顺序:先进行整数的遍历,再进行平方数遍历

        //5打印DP数组
        for(int i=0;i<=n;i++){
            cout<<dp[i]<<" ";
        }
        return dp[n];
    }
};

11.22 买卖股票的最佳时机III(leetcode123)

【题目】
image
【思路】

  • 本题与前两题的区别在于:本题限制交易次数只能够<=2,因此一共只有五种状态

a无操作
b第一次买入
c第一次卖出
d第二次买入
e第二次卖出

  • 注意:dp[i][1]并不是说一定要在第i天买入股票,而是持有当前买入股票的状态,注意区别上一题多次交易的情况
  • 代码步骤,代码随想录

1确定dp数组含义:dp[i][j]表示第i天所获得的最大利润,j=0~4表示5个状态
2初始化dp数组
3递推公式(五个状态):请注意--第i天的j状态只可能从第i-1天的j状态来或者是第i-1天的上一状态来
4递推遍历顺序
5打印dp数组

【代码】

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //遇上一题的区别:上一题不限次数,本题只能是0,1,2次
        //分析:在dp数组的构造上发生改变,一共是5个状态
        //无操作、第一次买入、第一次卖出、第二次买入、第二次卖出,最终状态是第二次卖出(如果有的话)dp[i][4]
        //因此根据以上五个操作写出递推公式

        //1确定dp数组含义:dp[i][j]表示第i天所获得的最大利润,j=0~4表示5个状态
        vector<vector<int>>dp(prices.size(),vector<int>(5,0));
        //2初始化dp数组
        dp[0][0]=0;
        dp[0][1]=0-prices[0];
        dp[0][2]=0;
        dp[0][3]=0-prices[0];
        dp[0][4]=0;
        //3递推公式(五个状态)
        for(int i=1;i<prices.size();i++){
            dp[i][0]=dp[i-1][0];//不操作
            dp[i][1]=max(dp[i-1][0]-prices[i],dp[i-1][1]);//第一次买入
            dp[i][2]=max(dp[i-1][1]+prices[i],dp[i-1][2]);//第一次卖出
            dp[i][3]=max(dp[i-1][2]-prices[i],dp[i-1][3]);//第一次买入
            dp[i][4]=max(dp[i-1][3]+prices[i],dp[i-1][4]);//第一次卖出
        }
        //4递推遍历顺序
        //5打印dp数组
        for(int i=0;i<prices.size();i++){
            cout<<dp[i][0]<<" "<<dp[i][1]<<" "<<dp[i][2]<<" "<<dp[i][3]<<" "<<dp[i][4]<<endl;
        }
        return dp[prices.size()-1][4];
    }
};

11.17 零钱兑换II(leetcode322)

【题目】
image
【思路】

  • 类比完全背包问题,采用动态规划
  • 由于要求的是最小数量,因此每次取min,按照硬币面值逐个做循环
  • 代码步骤如下(参照代码随想录)
  1. 确定dp数组下标及其含义:dp[i]代表凑出面值为i的总额需要的最小硬币数量
  2. 初始化数组(本次卡在这里):注意由于每次取最小因此全部初始化为MAX值,而dp[0]是递推根源为0
  3. 递推公式dp[i]=min{dp[i],dp[i-coins[j]]+1}
  4. 遍历顺序:由于无限多个硬币因此,外层走总额,内层走硬币种类
  5. 打印dp数组

【代码】

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        //1确定dp数组下标含义:dp[i]表示凑齐i元需要最少dp[i]枚硬币
        int size = coins.size();
        vector<int>dp(amount+1,65433);
        //2初始化dp[0]=0
        dp[0]=0;
        for(int i=0;i<=amount;i++){
            //int minNum = 1000;
            for(int j=0;j<size;j++){
                //3递推公式dp[i]=min(MIN,dp[i-coins[j]]+1)
                if(i>=coins[j])dp[i]=min(dp[i-coins[j]]+1,dp[i]);
            }
            //dp[i]=minNum;
        }
        //4确定递归遍历顺序:从小开始遍历i,从小开始遍历j 

        //5打印dp数组
        for(int i=0;i<=amount;i++){
            cout<<dp[i]<<" ";
        }
        if(dp[amount]==65433)return -1;
        return dp[amount];
    }
};

11.21 买卖股票的最佳时机II(leetcode122)

【题目】
image
【思路】

  • 构建dp数组:第i天可能持有股票也可能不持有股票(卡克点)
  • 最终待求的即为最后一天不持有股票的最大利润即dp[size-1][0]
  • 当前状态可能来自于前一天状态or当天改变状态
  • 代码步骤,代码随想录

1确定dp 数组下标及含义:dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润
2初始化dp
3动态转移方程:dp[i][0]=max(前一天不持有,今天卖出);dp[i][1]=max(前一天持有,今天买入);
4遍历顺序
5打印dp数组

【代码】

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //分析:构建dp数组:第i天可能持有股票也可能不持有股票
        //最终待求的即为最后一天不持有股票的最大利润即dp[size-1][0]
        //可能来自于当天卖出了股票dp[i-1][1]+prices[i]或是前一天本就不持有股票dp[i-1]

        //1确定dp 数组下标及含义:dp[i][0]表示第i天不持有股票的最大利润,dp[i][1]表示第i天持有股票的最大利润
        vector<vector<int>>dp(prices.size(),vector<int>(2,0));
        //2初始化dp
        dp[0][0]=0;
        dp[0][1]=0-prices[0];
        //3动态转移方程:dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
        for(int i=1;i<prices.size();i++){
            dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);
            dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
        }
        //4遍历顺序
        //5打印dp数组
        for(int i=1;i<prices.size();i++){
            cout << dp[i][0]<<" "<<dp[i][1]<<endl;
        }
        return dp[prices.size()-1][0];
    }
};

11.10 分割等和子集(leetcode416)

【题目】
image
【思路】

  • 分析:可以先对数组进行求和,由于数组内元素为整数,故和为奇数直接返回false
  • 类比01背包问题:将sum/2视作背包容量,将num[i]视为背包物品的重量和价值,若dp[sum/2]==sum/2则说明存在返回true
  • 动归五部曲
  1. 确定dp下标及其含义:dp[j]代表容量为j的背包能装入的最大价值(最大也不过j)
  2. 初始化dp为0
  3. 递推公式dp[j]=max(dp[j],dp[j-w[i]]+p[i])
  4. 确定遍历顺序:一维滚动数组为保证只取一次,选择倒序遍历
  5. 打印dp数组

【代码】

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum=0;
        for (int k = 0; k < nums.size(); k++) {
            sum += nums[k];
        }
        if (sum % 2 != 0)return false;
        int tar = sum / 2;
        //1dp数组含义dp[i]表示凑齐重量为i的最大数值总和
        vector<int>dp(tar + 1, 0);
        //2初始化数组dp=0
        for (int i = 0; i < nums.size(); i++) {
            //4确定遍历顺序:i--0~n-1,j--0~sum/2
            for (int j = tar;j>= nums[i]; j--) {
                //3确定递推公式
                dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
            }
        }
        //5打印dp数组
        for (int i = 0; i <= tar; i++)
            cout << dp[i] << " ";
        return dp[tar]==tar;
    }
};

11.20 买卖股票的最佳时机(leetcode121)

【题目】
image
【思路】

  • 动态规划法
  • 以最大利润(待求量)为dp数组构造条件
  • 代码步骤,参考代码随想录

1设置dp数组表示前i天的最大收益
2对dp数组进行初始化
3动态转移方程dp[i]=max(dp[i-1],price[i]-前i天的最小值)
4dp打印顺序
5打印dp数组

【代码】

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        //设置一个动态值为第i天前的最小买入
        int minN = prices[0];
        //1设置dp数组表示前i天的最大收益
        vector<int>dp(prices.size(),0);
        //2对dp数组进行初始化
        for(int i=1;i<prices.size();i++){
            minN = min(prices[i],minN);
            dp[i]=max(dp[i-1],prices[i]-minN);
        }
        //3动态转移方程dp[i]=max(dp[i-1],price[i]-min)
        //4dp遍历顺序
        //5打印dp数组
        for(int i=0;i<prices.size();i++){
            cout<<dp[i]<<" ";
        }
        return dp[prices.size()-1];
    }
};

6.4 颠倒字符串中的单词(leetcode151)

【题目】
image
【思路】

  • 双指针法:取ij双指针指代单词的开始和结束
  1. 当i为空则同时后移
  2. 当j为空则收集结果到数组中
  3. 当j为最后一个元素同样收集结果
  4. 反之j++向后遍历
  • 倒序输出数组结果

【代码】

class Solution {
public:
    string reverseWords(string s) {
        string ans = "";
        int i = 0, j = 0;
        vector<string>strs;
        while (i<=s.length()-1) {
            if (s[i] == ' ') {
                i++; j++;
            }
            else if (s[j] == ' ') {
                strs.push_back(s.substr(i, j - i));
                i = j;
            }
            else if (j == s.length() - 1) {
                strs.push_back(s.substr(i, j - i + 1));
                break;
            }
            else {
                j++;
            }
        }
        //倒序
        for (int i = strs.size() - 1; i >= 0; i--) {
            ans += strs[i];
            ans += ' ';
        }
        ans.pop_back();
        return ans;
    }
};

6.3 反转字符串II(leetcode541)

【题目】
image
【思路】

  • 总体思路--双指针
  • 分三种情况讨论

1 当前还能继续走2k--翻转前k
2 当前还能继续走k,无法走2k--翻转前k
3 当前k都走不了了--翻转所有

【代码】

class Solution {
public:
    string reverseStr(string s, int k) {
        int cur=0;
        while(cur<s.length()){
            int l=0,r=0;
            if(cur+2*k<s.length()){//>2k
                l=cur;
                r=cur+k-1;
            }
            else if(cur+k<s.length()){//k-2k
                l=cur;
                r=cur+k-1;
            }
            else{//<k
                l=cur;
                r=s.length()-1;
                
            }
            while(l<r){
                swap(s[l],s[r]);
                l++;r--;
            }
            cur+=2*k;
        }
        return s;
    }
};

11.23 买卖股票的最佳时机IV(leetcode188)

【题目】
image
【思路】

  • 注意:本题的交易次数为未知数,因此需要构造二维容器
  • 状态有三类:买入/卖出/无操作,分别对应j的奇偶性
  • 本题给出了prices范围可能是空串,因此要考虑空直接返回
  • 参考代码随想录,代码步骤

1dp数组下标及其含义:dp[i][j],i:0prices.size()-1,j:02k(j为奇数--买入,j为偶数--卖出)
2dp数组初始化:凡是买入就-
3递推公式,当前状态or前一状态的迁移
4遍历顺序:顺序
5打印dp数组

【代码】

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        //本题遇上一题的区别在于:交易数量是一个待定的值,并且长度可以是0!!!
        //因此在dp数组设置以及遍历得到递推公式需要特别注意
        //边界判定
        if(prices.empty())return 0;
        //1dp数组下标及其含义:dp[i][j],i:0~prices.size()-1,j:0~2k(j为奇数--买入,j为偶数--卖出)
        vector<vector<int>>dp(prices.size(),vector<int>(2*k+1,0));
        //2dp数组初始化:凡是买入就-
        for(int i=0;i<2*k+1;i++){
            if(i%2==1)dp[0][i]-=prices[0];
        }
        //3递推公式,当前状态or前一状态的迁移
        for(int i=1;i<prices.size();i++){
            for(int j=0;j<2*k+1;j++){
                if(j==0)dp[i][j]=dp[i-1][j];
                else if(j%2==1)dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]-prices[i]);
                else if(j%2==0)dp[i][j]=max(dp[i-1][j],dp[i-1][j-1]+prices[i]);
            }
        }
        //4遍历顺序
        //5打印dp数组
        for(int i=1;i<prices.size();i++){
            for(int j=0;j<2*k+1;j++){
                cout<<dp[i][j]<<" ";
            }
            cout<<endl;
        }
        return dp[prices.size()-1][2*k];
    }
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.