leetcode: String to Integer (atoi)

class Solution
{

    /**
     * @param String $s
     * @return Integer
     */
    public function myAtoi($s)
    {
        $s = ltrim($s);
        if (empty($s)) {
            return 0;
        }

        $ascii = ord($s[0]);
        $sign  = $ascii === 45;
        if ($ascii === 45 || $ascii === 43) {
            $sum = 0;
        } elseif ($ascii >= 48 && $ascii <= 57) {
            $sum = intval($s[0]);
        } else {
            return 0;
        }

        for ($i = 1, $len = strlen($s); $i < $len; ++$i) {
            $ascii = ord($s[$i]);
            if ($ascii < 48 || $ascii > 57) {
                break;
            }

            $sum = $sum * 10 + intval($s[$i]);
        }

        if ($sign) {
            $sum *= -1;
        }

        $boundry = pow(2, 31);
        if ($sum <= -$boundry) {
            return -$boundry;
        } elseif ($sum >= --$boundry) {
            return $boundry;
        }

        return $sum;
    }
}

leetcode: Palindrome Number

class Solution {

    /**
     * @param Integer $x
     * @return Boolean
     */
    function isPalindrome($x) {
        if($x >= 0 && $x < 10){
            return true;
        }

        if ($x < 0 || $x % 10 === 0) {
            return false;
        }


        return $this->reverse($x) === $x;
    }

    function reverse($x){
        $sum = 0;
        while($x >= 10){
            $last = $x % 10;
            $x = intval($x / 10);
            $sum = $sum * 10 + $last;
        }

        return $sum * 10 + $x;
    }
}

leetcode: Reverse Integer

class Solution
{

    /**
     * @param Integer $x
     * @return Integer
     */
    public function reverse($x)
    {
        if ($x < 10 && $x > -10) {
            return $x;
        }

        $reverse = 0;
        $unsign  = $x >= 0;
        $x       = abs($x);
        do {
            $last    = $x % 10;
            $reverse = $reverse * 10 + $last;
            $x       = intval($x / 10);
        } while ($x >= 10);
        $reverse = $reverse * 10 + $x;
        if (!$unsign) {
            $reverse = -$reverse;

            return $reverse < -(pow(2, 31)) ? 0 : $reverse;
        }

        return $reverse > (pow(2, 31) - 1) ? 0 : $reverse;
    }
}

leetcode: ZigZag Conversion

/*
 * @lc app=leetcode id=6 lang=php
 *
 * [6] ZigZag Conversion
 */

// @lc code=start
class Solution {

    /**
     * @param String $s
     * @param Integer $numRows
     * @return String
     */
    function convert($s, $numRows) {
        $len = strlen($s);
        if ($len === 1 || $numRows === 1) {
            return $s;
        }

        $max = 2 * $numRows - 2;
        
        $str = '';
        // 0 4 8 12
        // 1 3 5 7 9 11 13
        // 2 6 10

        // 0   6    12
        // 1 5 7 11 13
        // 2 4 8 10
        // 3   9    [15]

        // P   H
        // A S I
        // Y I R
        // P L I G
        // A   N
        // 0   8
        // 1 7 9
        // 2 6 10
        // 3 5 11 13
        // 4   12
        
        //ABCDEFGHIJKLMNOPQRSTUVWXYZ
        //A   E   I   M   Q   U   Y
        //B D F H J L N P R T V X Z
        //C   G   K   O   S   W
        //0   4   8    12    16 --- 4
        //1 3 5 7 9 11 13 15 17 --- 2
        //2   6   10   14    18 --- 4
        
        //A   G   M
        //B F H L N R
        //C E I K O Q
        //D   J   P
        //0   6    12    18    6
        //1 5 7 11 13 17 19    4
        //2 4 8 10 14 16 20    2
        //3   9    15    21

        //A   I   Q
        //B H J P R
        //C G K O S
        //D F L N T
        //E   M   U
        //0   8     16    24    8
        //1 7 9  15 17 23 25    6 2 6 2
        //2 6 10 14 18 22       4 4 4 4
        //3 5 11 13 19 21       2 6 2 6
        //4   12    20          8

        //A   K   U
        //B J L T V
        //C I M S W
        //D H N R
        //E G O Q
        //F   P
        //0   10    20   10
        //1 9 11 19 21   8 2 8 2
        //2 8 12 18 22   6 4 6 4
        //3 7 13 17 23   4 6 4 6
        //4 6 14 16 24   2 8 2 8
        //5   15    25   10
        $arr[] = [0, $max];
        $j = 2;
        while($max - $j > 0) {
            $arr[] = [$max - $j, $j];
            $j += 2;
        }
        $arr[] = [0, $max];

        for ($i = 0; $i < $numRows; $i++) {
            $str .= $s[$i];
            $idx = $i;
            while(true) {
                foreach($arr[$i] as $val) {
                    $idx += $val;
                    if($idx >= $len) {
                        break 2;
                    }
                    
                    if (!$val) {
                        continue;
                    }

                    $str .= $s[$idx];
                }
            }
        }

        return $str;
    }
}
// @lc code=end

leetcode: longest substring without repeating characters

  • 问题

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

  • leetcode类别

中等

  • 代码
class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function lengthOfLongestSubstring($s) {
        $len1 = strlen($s);
        if (!$len1) {
            return $len1;
        }

        $max = 1;
        $p = [];
        for($i = 0, $j = 0; $i < $len1; $i++) {
            $code = ord($s[$i]);
            if (!array_key_exists($code, $p)) {
                $p[$code] = $i;
                continue;
            }
            
            $strlen = $i - $j;
            $max = $strlen > $max ? $strlen : $max;
            $i = $p[$code];
            $j = $i + 1;
            $p = [];
        }
        
        $cnt = count($p);
        $max = $cnt > $max ? $cnt : $max;
        
        return $max;
    }
}

leetcode:add-two-numbers

  • 问题

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

  • leetcode类别

中等

  • 代码
/**
 * Definition for a singly-linked list.
 * class ListNode {
 *     public $val = 0;
 *     public $next = null;
 *     function __construct($val = 0, $next = null) {
 *         $this->val = $val;
 *         $this->next = $next;
 *     }
 * }
 */
class Solution {

    /**
     * @param ListNode $l1
     * @param ListNode $l2
     * @return ListNode
     */
    function addTwoNumbers($l1, $l2) {
        return $this->reverseList($this->getNode($l1, $l2));
    }

    function reverseList($list) {
        $prev = null;
        while($list !== null) {
            $node = new ListNode($list->val, null);
            $node->next = $prev;

            $prev = $node;
            $list = $list->next;
        }

        return $node;
    }

    function getNode($l1, $l2) {
        $prev = null;
        $plus = 0;
        
        while(true) {
            if ($l1 === null && $l2 === null && !$plus) {
                break;
            }

            $val = 0;
            if ($l1 !== null) {
                $val += $l1->val;
            }

            if ($l2 !== null) {
                $val += $l2->val;
            }

            $val += $plus;

            $plus = 0;
            if ($val > 9) {
                $val = $val % 10;
                $plus = 1;
            }
            
            $node = new ListNode($val, null);
            $node->next = $prev;

            $prev = $node;
            
            if ($l1 !== null) {
                $l1 = $l1->next;
            }

            if ($l2 !== null) {
                $l2 = $l2->next;
            }
        }

        return $node;
    }
}

leetcode:two-sum

  • 问题

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

  • leetcode类别

简单

  • 代码
class Solution {

    /**
     * @param Integer[] $nums
     * @param Integer $target
     * @return Integer[]
     */
    function twoSum($nums, $target) {
        $len = count($nums);

        for ($i = 0; $i < $len - 1; ++$i) {
            $sub = $target - $nums[$i];
            for ($j = $i + 1; $j < $len; ++$j) {
                if ($nums[$j] === $sub) {
                    return [$i, $j];
                }
            }
        }

        return [];
    }
}

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

Elasticsearch在启动时出现错误:

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

这个问题是虚拟内存设置问题。在虚拟内存有说明:Elasticsearch默认使用mmapfs类型存储文档。对mmapfs的介绍,Elasticsearch文档也有说明。系统默认是65530,对Elasticsearch远远不够。

  • 解决办法

修改/etc/sysctl.conf,如果文件内有vm.max_map_count项,那么修改值大于或等于报错值262144。如果没有,在末尾追加一行。

修改完之后再终端执行sysctl --system或者sysctl -p使修改生效。检查是否生效可以使用sysctl vm.max_map_count查看。

vagrant增加虚拟机磁盘空间

vagrant中增加磁盘空间,可以使用插件vagrant-disksize

  • 插件安装
vagrant plugin install vagrant-disksize

如果出现超时错误,需要终端设置代理。安装好之后,如果虚拟机已经在运行,先使用vagrant halt关闭,在Vagrantfile中添加配置:

config.disksize.size = '50GB'

保存后再使用vagrant up启动。启动时,看到一段话:

==> machine5: Resized disk: old 10240 MB, req 51200 MB, new 51200 MB
==> machine5: You may need to resize the filesystem from within the guest.
  • 配置

启动后进入系统,使用df查看发现,磁盘空间没有还是变化。需要下面几个步骤:

  1. 运行sudo cfdisk /dev/sda,这时候能够看到新增的空间了。如我的原本是10GB,配置里改为了50GB,这里就看到两行,第一行是/dev/sda110GB,第二行是新增的40GB
  2. 使用上下箭头选中第一行,再使用左右箭头选中Resize,后面的提示New size: 50G按回车确认。
  3. 再使用左右箭头选择Write,显示提示Are you sure you want to write the partition table to disk?时输入yes按回车确认。
  4. 选择Quit回车。
  5. 运行sudo resize2fs -p -F /dev/sdaX,X替换为自己对应的数字。如果是centos 7,8这里会提示:resize2fs: Bad magic number in super-block while trying to open /dev/sda1. Couldn't find valid filesystem superblock.换成运行xfs_grows /dev/sda1

最后,使用df查看,磁盘空间已经增加。

使用logstash将MySQL数据同步到elasticsearch

安装logstash

logstash下载地址:https://www.elastic.co/downloads/logstash,这里只显示了最新版本,历史版本地址:https://www.elastic.co/downloads/past-releases#logstash

下载好解压后简单配置下logstash.conf(解压后在config下有一个logstash-sample.conf文件,复制为logstash.conf,其他命名也行)就可以使用了。如果你的版本是7.6(不包括)以下,还需要安装logstash-integration-jdbc插件,7.6以上该插件已经集成到logstash中,无需额外安装。

配置

输入配置

默认配置文件打开,在input里有个beats的配置删掉,插入jdbc配置

jdbc {
    jdbc_driver_library => "mysql-connector-java-5.1.36-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://数据库地址:3306/数据库名字"
    jdbc_user => "数据库账号"
    jdbc_password => "数据库密码"
    schedule => "* * * * *这里和Linux的crontab配置一样"
    statement => "查询出要同步到elasticsearch的数据"
    use_column_value => true
    tracking_column => "update_time"
    tracking_column_type => "timestamp"
  }
  • use_column_value

值为布尔值,这里影响sql_last_value的值,默认为falsesql_last_value使用上次执行时间,初始值为1970-01-01零点。设置为true,那么这里是tracking_column配置字段的值,如tracking_column => "id",那么这里就是上次执行的id值。

  • tracking_column

数据库字段,sql判断条件。如主键、更新时间等。

  • tracking_column_type

上面字段值的类型,有两个值可选:timestampnumeric。默认为numeric。影响sql_last_value,如上面字段update_time假设为时间戳,但是这里设置为timestamp,那么sql_last_value初始值为1970-01-01,这就会使sql_last_value一直停留在初始值。设置为numeric,初始值为0

输出配置

默认配置:

elasticsearch {
   hosts => ["http://localhost:9200"]
   index => ""
   document_id => "%{elasticsearch使用哪个字段作主键ID}"
   #user => "elastic"
   #password => "changeme"
 }

hosts需要改为自己的elasticsearch地址。虽然,参数document_type参数还存在,但是默认是会将数据同步到_doc下面。从elastcisearch的6.0开始便不再推荐使用type,7.0以上的版本已经废弃,而8.0版本会直接移除。详细说明:removal of mapping types

这样已经能满足数据同步了,如有其它需求可根据参数说明文档作调整。

  • 启动

启动logstash只需进入到bin目录,执行:

./logstash -f /配置文件路径/xxx.conf

logstash配置

logstash配置分为三个部分:input(输入)、filter(过滤)、output(输出)。

  • jdbc中last_run_metadata_path设置的路径需有读写权限。如果没有写入权限,变量sql_last_value虽然会记录上一次的值,但在重新启动后,值会从0开始。

  • 启动时提示:

WARN: Establishing SSL connection without server’s identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn’t set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to ‘false’. You need eit
her to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

在jdbc_connection_string配置后面加上参数:useSSL=false&verifyServerCertificate=false即可。

  • MySQL中tinyint(1)字段值jdbc读取后会被转换为布尔值。同样在jdbc_connection_string后面加上参数:tinyInt1isBit=false&transformedBitIsBoolean=false可以保持原值不被转换。