Leetcode 解题记录

1. 两数之和;

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
示例:输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
链接:https://leetcode-cn.com/problems/two-sum/

<?php 
class Solution {

    /**
     * @param Integer[] $nums
     * @param Integer $target
     * @return Integer[]
     */
    function twoSum($nums, $target) {
        $count = sizeof($nums);
        for ($i=0; $i<=$count; $i++) {
            for ($j=$i; $j<=$count; $j++) {
                if (($i != $j) && ($nums[$i] + $nums[$j] == $target)) {
                    return [$i, $j];
                }
            }
        }
        return 'error';
    }
}

2. 两数相加;

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
链接:https://leetcode-cn.com/problems/add-two-numbers/

<?php
/**
 * 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(ListNode $l1, ListNode $l2) {
        $list = new ListNode(0);
        $p = $l1; 
        $q = $l2; 
        $curr = $list;
        $carry = 0;
        while ($l1 != null || $l2 != null) {
            $x = ($l1 != null) ? $l1->val : 0;
            $y = ($l2 != null) ? $l2->val : 0;
            $sum = $carry + $x + $y;
            $carry = intval($sum / 10); // 按10进位
            $curr->next = new ListNode($sum % 10);
            $curr = $curr->next;
            if ($l1 != null) $l1 = $l1->next;
            if ($l2 != null) $l2 = $l2->next;
        }
    
        // 最后两数相加有进位处理
        if ($carry > 0) {
            $curr->next = new ListNode($carry);
        }
        return $list->next;
    }

    /**
    * 链表转数组
    *
    * @param ListNode $data
    * @return array
    */
    function listToArray(ListNode $data) {
        $result = [];
        while ($data != null) {
            $result[] = $data->val;
            $data = $data->next;
        }
    
        return $result;
    }

    /**
    * 数组转链表
    *
    * @param array $data
    * @return ListNode
    */
    function arrayToList($data) {  
        $list = new ListNode();
        
        if (!empty($data)) {
            $list = new ListNode(array_shift($data));
            $temp = $list;

            foreach ($data as $v) {
                $temp->next = new ListNode($v);
                $temp = $temp->next;
            }
        }
        
        return $list;
    }
    
}
$s = new Solution();
$l1 = $s->arrayToList([2, 4, 3]);
$l2 = $s->arrayToList([5, 6, 4]);
$r = $s->addTwoNumbers($l1 , $l2);

另:

/**
 * 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) {
        $list = new ListNode();
        $this->getSumList($l1,$l2,$list);
        return $list->next;
    }

    function getSumList($l1,$l2,$list,$add=0){
        if($l1 === null && $l2 === null && $add ==0){
            return $list;
        }
        $tmp = $l1->val+$l2->val+$add;
        $tmp_list = new ListNode($tmp%10);
        $list->next = $tmp_list;
        $l1 = $l1->next;
        $l2 = $l2->next;
        return $this->getSumList($l1,$l2,$tmp_list,$tmp>=10?1:0);
    }
}

3. 无重复字符的最长子串;

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

<?php
class Solution {

    /**
     * @param String $s
     * @return Integer
     */
    function lengthOfLongestSubstring($s) {
        $length = strlen($s);
        if ($length == 0) return 0;
        
        $array = [];
        $max = 0;	// 长度
        $index = 0;	// 开始位置
        
        for ($i = 0; $i<$length; $i++) {
            // 存在map
            if (isset($array[$s[$i]]) && $index <= $array[$s[$i]]) {
                $index = $array[$s[$i]]+1;
            } else {
                $max = max($max, $i-$index+1);
            }
            
            $array[$s[$i]] = $i;
        }
        
        return $max;
    }
}

4. 寻找两个正序数组的中位数;

给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
示例:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2

<?php
class Solution {

    /**
     * @param Integer[] $nums1
     * @param Integer[] $nums2
     * @return Float
     */
    function findMedianSortedArrays($nums1, $nums2) {
        $d = array_merge($nums1, $nums2); 
	
        $len = count($d);
        if ($len>0) {
            sort($d);
            $index = $len/2;
            if(is_int($index)){
                $mid = ($d[$index-1] + $d[$index])/2;
            }else{
                $mid =  $d[intval($index)];
            }
        }
        
        return $mid;
    }
}

5. 最长回文子串;

给你一个字符串 s,找到 s 中最长的回文子串。
示例:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

// 暴力解法,但是系统返回:超出时间限制(作为一种思路提供)
class Solution {

    /**
     * @param String $s
     * @return String
     */
    function longestPalindrome($s) {
        $len = strlen($s);
        if ($len < 2) {
            return $s; 
        }
        
        $max = '';
        for ($i = 0; $i<=$len; $i++) {
            for ($j = $i+1; $j<=$len; $j++) {
                $str = substr($s, $i, $j-$i);
                $restr = strrev($str);
                if ($str == $restr && strlen($str) > strlen($max)) {
                    $max = $str;
                }
            }
        }
        return $max;
    }
}

另:动态规划

字符串:ABCDDCEFA
dp[i][j]=true, i 是终止字符,j 是起始字符
d[0][0] = true
d[4][3] = true 表示字符串从str[3]到str[4] = DD
d[5][2] = true 表示字符串从str[2]到str[5] = CDDC
由此可见,当子串两端的字符str[i]=str[j]时,再判断去掉两端字符的子串d[i-1][j+1]是否是回文。
如果是回文,即d[i-1][j+1]=1,则d[i][j]是回文

动态规划概念

  1. 最优子结构:当 str [8]=str [0] 时,判断 d [7][1],即从 str [1] 到 str [7] 是否是回文
  2. 边界:
    d[0][0] = 1
  3. 转态转移公式:
    d [i][j] = 1 , i-j<3, str [i]=str [j] 因为小于 3 个字符一定是回文,例 A、AA、ABA
    d[i][j] = d[i-1][j+1] , i-j>3, str[i]=str[j]
class Solution {

    /**
     * @param String $s
     * @return String
     */
    function longestPalindrome($s) {
        $len = strlen($s);
        if($len < 2) {
            return $s;
        }

        $dp = [];
        $max = 1;	// 回文字符串长度
        $right = $left = 0;
        
        // $j起始,$i结束
        for($i=0; $i<$len; $i++) {
            for($j=0; $j<=$i; $j++) {
            
                $dp[$i][$j] = false; // 初始值
                if ($s[$i] == $s[$j]) {
                    if ($i-$j < 3) {	// 最多三个字符回文(eg:aba)
                        $dp[$i][$j] = true;
                    } else {
                        if ($dp[$i-1][$j+1] == true) {
                            $dp[$i][$j] = true;
                        }
                    }
                    
                    if ($i-$j+1>$max && $dp[$i][$j] == true) {
                        $max = $i-$j+1;
                        $right = $i;
                        $left = $j;
                    }
                }
            }
        }

        return substr($s,$left,$right-$left+1);
    }
}

6. Z 字形变换;

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列
比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串
如:“PAHNAPLSIIGYIR”。

class Solution {

    /**
     * @param String $s
     * @param Integer $numRows
     * @return String
     */
    function convert($s, $numRows) {
        $len = strlen($s);
    	$arr = [];	// 结果数组
    	$str = '';
    	$i = 0;
    	$n = 0;
    	
    	while ($i < $len) {
    		// 竖线
    		for ($m=0; $m<$numRows; $m++) {
    			if ($i >= $len)	break;
    			
    			$arr[$m][$n] = $s[$i];
    			$i++;
    		}
    		
    		// 斜线
    		for ($m=$numRows-2; $m>0; $m--) {
                if ($i >= $len)	break;
                
                $n++;
                $arr[$m][$n] = $s[$i];
                $i++;
            }
            
            $n++;
    	}
    	
    	foreach ($arr as $v) {
    		$str = $str . implode("", $v);
    	}
    	
    	return $str;
    }
}

7. 整数反转;

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
输入:x = 123
输出:321

class Solution {

    /**
     * @param Integer $x
     * @return Integer
     */
    function reverse($x) {
        $min = pow(-2, 31);
        $max = pow(2, 31)-1;
        $rev = intval(strrev(trim($x)));

        if ($rev > $max || $rev < $min) {
            return 0;
        }
        
        if ($x >= 0) {
            return $rev;
        } else {
            return "-" . $rev;
        }
            
    }
}

9. 回文数;

class Solution {

    /**
     * @param Integer $x
     * @return Boolean
     */
    function isPalindrome($x) {
        return strrev($x) == $x;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值