├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── Pipfile ├── Pipfile.lock ├── README.md ├── README_leetcode_generate.md ├── config.cfg.example ├── demo └── leetcode.gif ├── leetcode_generate.py ├── req.txt └── solutions ├── 0001-two-sum ├── two-sum.py └── two-sum.rs ├── 0002-add-two-numbers └── add-two-numbers.py ├── 0003-longest-substring-without-repeating-characters └── longest-substring-without-repeating-characters.py ├── 0004-median-of-two-sorted-arrays └── median-of-two-sorted-arrays.py ├── 0005-longest-palindromic-substring └── longest-palindromic-substring.py ├── 0006-zigzag-conversion └── zigzag-conversion.py ├── 0007-reverse-integer └── reverse-integer.py ├── 0008-string-to-integer-atoi └── string-to-integer-atoi.py ├── 0009-palindrome-number └── palindrome-number.py ├── 0010-regular-expression-matching └── regular-expression-matching.py ├── 0011-container-with-most-water └── container-with-most-water.py ├── 0012-integer-to-roman └── integer-to-roman.py ├── 0013-roman-to-integer └── roman-to-integer.py ├── 0014-longest-common-prefix └── longest-common-prefix.py ├── 0015-3sum └── 3sum.py ├── 0016-3sum-closest └── 3sum-closest.py ├── 0017-letter-combinations-of-a-phone-number └── letter-combinations-of-a-phone-number.py ├── 0018-4sum └── 4sum.py ├── 0019-remove-nth-node-from-end-of-list └── remove-nth-node-from-end-of-list.py ├── 0020-valid-parentheses └── valid-parentheses.py ├── 0021-merge-two-sorted-lists └── merge-two-sorted-lists.py ├── 0022-generate-parentheses └── generate-parentheses.py ├── 0023-merge-k-sorted-lists └── merge-k-sorted-lists.py ├── 0024-swap-nodes-in-pairs └── swap-nodes-in-pairs.py ├── 0025-reverse-nodes-in-k-group └── reverse-nodes-in-k-group.py ├── 0026-remove-duplicates-from-sorted-array └── remove-duplicates-from-sorted-array.py ├── 0027-remove-element └── remove-element.py ├── 0028-implement-strstr └── implement-strstr.py ├── 0034-find-first-and-last-position-of-element-in-sorted-array └── find-first-and-last-position-of-element-in-sorted-array.py ├── 0035-search-insert-position └── search-insert-position.py ├── 0038-count-and-say └── count-and-say.py ├── 0039-combination-sum └── combination-sum.py ├── 0041-first-missing-positive └── first-missing-positive.py ├── 0048-rotate-image └── rotate-image.py ├── 0050-powx-n └── powx-n.py ├── 0053-maximum-subarray └── maximum-subarray.py ├── 0054-spiral-matrix └── spiral-matrix.py ├── 0055-jump-game └── jump-game.py ├── 0056-merge-intervals └── merge-intervals.py ├── 0057-insert-interval └── insert-interval.py ├── 0058-length-of-last-word └── length-of-last-word.py ├── 0066-plus-one └── plus-one.py ├── 0067-add-binary └── add-binary.py ├── 0070-climbing-stairs └── climbing-stairs.py ├── 0071-simplify-path └── simplify-path.py ├── 0073-set-matrix-zeroes └── set-matrix-zeroes.py ├── 0075-sort-colors └── sort-colors.py ├── 0077-combinations └── combinations.py ├── 0078-subsets └── subsets.py ├── 0079-word-search └── word-search.py ├── 0080-remove-duplicates-from-sorted-array-ii └── remove-duplicates-from-sorted-array-ii.py ├── 0083-remove-duplicates-from-sorted-list └── remove-duplicates-from-sorted-list.py ├── 0086-partition-list └── partition-list.py ├── 0088-merge-sorted-array └── merge-sorted-array.py ├── 0093-restore-ip-addresses └── restore-ip-addresses.py ├── 0094-binary-tree-inorder-traversal └── binary-tree-inorder-traversal.py ├── 0097-interleaving-string └── interleaving-string.py ├── 0100-same-tree └── same-tree.py ├── 0101-symmetric-tree └── symmetric-tree.py ├── 0104-maximum-depth-of-binary-tree └── maximum-depth-of-binary-tree.py ├── 0107-binary-tree-level-order-traversal-ii └── binary-tree-level-order-traversal-ii.py ├── 0108-convert-sorted-array-to-binary-search-tree └── convert-sorted-array-to-binary-search-tree.py ├── 0111-minimum-depth-of-binary-tree └── minimum-depth-of-binary-tree.py ├── 0112-path-sum └── path-sum.py ├── 0113-path-sum-ii └── path-sum-ii.py ├── 0118-pascals-triangle └── pascals-triangle.py ├── 0119-pascals-triangle-ii └── pascals-triangle-ii.py ├── 0121-best-time-to-buy-and-sell-stock └── best-time-to-buy-and-sell-stock.py ├── 0122-best-time-to-buy-and-sell-stock-ii └── best-time-to-buy-and-sell-stock-ii.py ├── 0125-valid-palindrome └── valid-palindrome.py ├── 0134-gas-station └── gas-station.py ├── 0136-single-number └── single-number.py ├── 0137-single-number-ii └── single-number-ii.py ├── 0141-linked-list-cycle └── linked-list-cycle.py ├── 0189-rotate-array └── rotate-array.py ├── 0206-reverse-linked-list └── reverse-linked-list.py ├── 0227-basic-calculator-ii └── basic-calculator-ii.py ├── 0237-delete-node-in-a-linked-list └── delete-node-in-a-linked-list.py ├── 0240-search-a-2d-matrix-ii └── search-a-2d-matrix-ii.py ├── 0242-valid-anagram └── valid-anagram.py ├── 0263-ugly-number └── ugly-number.py ├── 0264-ugly-number-ii └── ugly-number-ii.py ├── 0274-h-index └── h-index.py ├── 0275-h-index-ii └── h-index-ii.py ├── 0313-super-ugly-number └── super-ugly-number.py ├── 0324-wiggle-sort-ii └── wiggle-sort-ii.py ├── 0335-self-crossing └── self-crossing.py ├── 0347-top-k-frequent-elements └── top-k-frequent-elements.py ├── 0405-convert-a-number-to-hexadecimal └── convert-a-number-to-hexadecimal.py ├── 0420-strong-password-checker └── strong-password-checker.py ├── 0438-find-all-anagrams-in-a-string └── find-all-anagrams-in-a-string.py ├── 0454-4sum-ii └── 4sum-ii.py ├── 0455-assign-cookies └── assign-cookies.py ├── 0458-poor-pigs └── poor-pigs.py ├── 0461-hamming-distance └── hamming-distance.py ├── 0485-max-consecutive-ones └── max-consecutive-ones.py ├── 0506-relative-ranks └── relative-ranks.py ├── 0526-beautiful-arrangement └── beautiful-arrangement.py └── 1065-binary-string-with-substrings-representing-1-to-n └── binary-string-with-substrings-representing-1-to-n.py /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: ["https://paypal.me/foreverbonfy", "https://raw.githubusercontent.com/bonfy/image/master/global/sponsor.jpg"] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # bonfy add this 101 | 102 | old/ 103 | cookies.json 104 | log/ 105 | *.err 106 | 107 | .vscode/ 108 | *.out 109 | .envrc 110 | 111 | # Do not push sensitive files 112 | config.cfg -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.5" 4 | 5 | before_install: 6 | - phantomjs --version # 输出 phantomjs 版本 7 | 8 | # command to install dependencies 9 | install: 10 | - pip install -r req.txt 11 | 12 | before_script: 13 | - ls 14 | 15 | script: 16 | - python3 leetcode_generate.py 17 | 18 | after_script: 19 | - git init 20 | - git config user.name "bonfy" #修改name 21 | - git config user.email "foreverbonfy@163.com" #修改email 22 | - git add . 23 | - git commit -m "update auto by tracis-ci" 24 | - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master #GH_TOKEN是在Travis中配置token的名称 25 | 26 | env: 27 | global: 28 | - GH_REF: github.com/bonfy/leetcode 29 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.python.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | requests = ">=2.20.0" 8 | selenium = "==3.11.0" 9 | certifi = "==2018.1.18" 10 | chardet = "==3.0.4" 11 | cssselect = "==1.0.3" 12 | idna = "==2.6" 13 | lxml = "==4.2.1" 14 | pyquery = "==1.4.0" 15 | "urllib3" = ">=1.23" 16 | 17 | [dev-packages] 18 | 19 | [requires] 20 | python_version = "3.7" 21 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "e53e1a54bc8f865390d8c4fe3e62341e5a6e331b3597dc23c2918e72761a833d" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.7" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.python.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "certifi": { 20 | "hashes": [ 21 | "sha256:14131608ad2fd56836d33a71ee60fa1c82bc9d2c8d98b7bdbc631fe1b3cd1296", 22 | "sha256:edbc3f203427eef571f79a7692bb160a2b0f7ccaa31953e99bd17e307cf63f7d" 23 | ], 24 | "index": "pypi", 25 | "version": "==2018.1.18" 26 | }, 27 | "chardet": { 28 | "hashes": [ 29 | "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", 30 | "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" 31 | ], 32 | "index": "pypi", 33 | "version": "==3.0.4" 34 | }, 35 | "cssselect": { 36 | "hashes": [ 37 | "sha256:066d8bc5229af09617e24b3ca4d52f1f9092d9e061931f4184cd572885c23204", 38 | "sha256:3b5103e8789da9e936a68d993b70df732d06b8bb9a337a05ed4eb52c17ef7206" 39 | ], 40 | "index": "pypi", 41 | "version": "==1.0.3" 42 | }, 43 | "idna": { 44 | "hashes": [ 45 | "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f", 46 | "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4" 47 | ], 48 | "index": "pypi", 49 | "version": "==2.6" 50 | }, 51 | "lxml": { 52 | "hashes": [ 53 | "sha256:01c45df6d90497c20aa2a07789a41941f9a1029faa30bf725fc7f6d515b1afe9", 54 | "sha256:0c9fef4f8d444e337df96c54544aeb85b7215b2ed7483bb6c35de97ac99f1bcd", 55 | "sha256:0e3cd94c95d30ba9ca3cff40e9b2a14e1a10a4fd8131105b86c6b61648f57e4b", 56 | "sha256:0e7996e9b46b4d8b4ac1c329a00e2d10edcd8380b95d2a676fccabf4c1dd0512", 57 | "sha256:1858b1933d483ec5727549d3fe166eeb54229fbd6a9d3d7ea26d2c8a28048058", 58 | "sha256:1b164bba1320b14905dcff77da10d5ce9c411ac4acc4fb4ed9a2a4d10fae38c9", 59 | "sha256:1b46f37927fa6cd1f3fe34b54f1a23bd5bea1d905657289e08e1297069a1a597", 60 | "sha256:231047b05907315ae9a9b6925751f9fd2c479cf7b100fff62485a25e382ca0d4", 61 | "sha256:28f0c6652c1b130f1e576b60532f84b19379485eb8da6185c29bd8c9c9bc97bf", 62 | "sha256:34d49d0f72dd82b9530322c48b70ac78cca0911275da741c3b1d2f3603c5f295", 63 | "sha256:3682a17fbf72d56d7e46db2e80ca23850b79c28cfe75dcd9b82f58808f730909", 64 | "sha256:3cf2830b9a6ad7f6e965fa53a768d4d2372a7856f20ffa6ce43d2fe9c0d34b19", 65 | "sha256:5b653c9379ce29ce271fbe1010c5396670f018e78b643e21beefbb3dc6d291de", 66 | "sha256:65a272821d5d8194358d6b46f3ca727fa56a6b63981606eac737c86d27309cdd", 67 | "sha256:691f2cd97cf026c611df1ea5055755eec7f878f2d4f4330dc8686583de6fc5fd", 68 | "sha256:6b6379495d3baacf7ed755ac68547c8dff6ce5d37bf370f0b7678888dc1283f9", 69 | "sha256:75322a531504d4f383264391d89993a42e286da8821ddc5ac315e57305cb84f0", 70 | "sha256:7f457cbda964257f443bac861d3a36732dcba8183149e7818ee2fb7c86901b94", 71 | "sha256:7ff1fc76d8804e0f870c343a72007ff587090c218b0f92d8ee784ac2b6eaf5b9", 72 | "sha256:8523fbde9c2216f3f2b950cb01ebe52e785eaa8a07ffeb456dd3576ca1b4fb9b", 73 | "sha256:8f37627f16e026523fca326f1b5c9a43534862fede6c3e99c2ba6a776d75c1ab", 74 | "sha256:a7182ea298cc3555ea56ffbb0748fe0d5e0d81451e2bc16d7f4645cd01b1ca70", 75 | "sha256:abbd2fb4a5a04c11b5e04eb146659a0cf67bb237dd3d7ca3b9994d3a9f826e55", 76 | "sha256:accc9f6b77bed0a6f267b4fae120f6008a951193d548cdbe9b61fc98a08b1cf8", 77 | "sha256:bd88c8ce0d1504fdfd96a35911dd4f3edfb2e560d7cfdb5a3d09aa571ae5fbae", 78 | "sha256:c557ad647facb3c0027a9d0af58853f905e85a0a2f04dcb73f8e665272fcdc3a", 79 | "sha256:defabb7fbb99f9f7b3e0b24b286a46855caef4776495211b066e9e6592d12b04", 80 | "sha256:e2629cdbcad82b83922a3488937632a4983ecc0fed3e5cfbf430d069382eeb9b" 81 | ], 82 | "index": "pypi", 83 | "version": "==4.2.1" 84 | }, 85 | "pyquery": { 86 | "hashes": [ 87 | "sha256:07987c2ed2aed5cba29ff18af95e56e9eb04a2249f42ce47bddfb37f487229a3", 88 | "sha256:4771db76bd14352eba006463656aef990a0147a0eeaf094725097acfa90442bf" 89 | ], 90 | "index": "pypi", 91 | "version": "==1.4.0" 92 | }, 93 | "requests": { 94 | "hashes": [ 95 | "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", 96 | "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" 97 | ], 98 | "index": "pypi", 99 | "version": "==2.22.0" 100 | }, 101 | "selenium": { 102 | "hashes": [ 103 | "sha256:2b6f018e55f50e9c67a67caec2f73f806f72c162fb38cf3ea79e0a8f6506bf56", 104 | "sha256:5841fb30c3965866220c34d16de8e3d091e2833fcac385160a63db0c3522a297" 105 | ], 106 | "index": "pypi", 107 | "version": "==3.11.0" 108 | }, 109 | "urllib3": { 110 | "hashes": [ 111 | "sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1", 112 | "sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232" 113 | ], 114 | "index": "pypi", 115 | "version": "==1.25.3" 116 | } 117 | }, 118 | "develop": {} 119 | } 120 | -------------------------------------------------------------------------------- /README_leetcode_generate.md: -------------------------------------------------------------------------------- 1 | # leetcode_generate Usage 2 | 3 | ![](https://github.com/bonfy/leetcode/blob/master/demo/leetcode.gif) 4 | 5 | ## Preparements: 6 | 7 | Use `selenium` and `chromedriver` 8 | 9 | > I think it's not the best way. But I can't find way leetcode encrypt the csrftoken. 10 | > If anyone find the encrypt algoristhm, please pull request to me. And I can change the login to requests 11 | 12 | Mac Users can install `Chromedriver` by `Homebrew` 13 | 14 | ``` cmd 15 | $ brew install chromedriver 16 | ``` 17 | 18 | Centos users install `chromedriver` 19 | 20 | ``` 21 | # Install chromium 22 | $ sudo yum install -y chromium 23 | 24 | # Install chromedriver 25 | $ yum install -y chromedriver 26 | 27 | # soft link 28 | $ ln -s /usr/bin/chromedriver /usr/local/bin/chromedriver 29 | ``` 30 | 31 | Install essential packages: `requests`, `pyquery`,`selenium` 32 | ```cmd 33 | $ pyvenv venv # create virtual environment 34 | $ source venv/bin/activate 35 | $ pip3 install -r req.txt 36 | ``` 37 | or if you use Pipenv 38 | 39 | ``` 40 | $ pipenv install 41 | ``` 42 | 43 | ## Config: 44 | 45 | Edit your own username, password, language and repo in the **config.cfg.example** file and then rename it to **config.cfg**. 46 | 47 | driverpath - Set the path of chromedriver. For Windows users, please include **chromedriver.exe** in path. 48 | 49 | ``` 50 | [leetcode] 51 | 52 | username = username 53 | password = password 54 | language = python 55 | repo = https://github.com/bonfy/leetcode 56 | driverpath = /usr/local/bin/chromedriver 57 | ``` 58 | 59 | ## Run 60 | 61 | ### Fully Download 62 | ```cmd 63 | python3 leetcode_generate.py 64 | ``` 65 | Usually you can always run fully download 66 | 67 | ### Download by id 68 | ``` 69 | python3 leetcode_generate.py 1 70 | python3 leetcode_generate.py 1 10 100 71 | ``` 72 | You can only download the solution you want. 73 | Just add the id arguments behind (seperate by space) 74 | 75 | 76 | ## Attention 77 | Python 3 have tested 78 | 79 | Python 2 maybe 80 | 81 | ## Sponsor 82 | 83 | ![support](http://7i7k6w.com1.z0.glb.clouddn.com/weixin_alipay_new.jpg) 84 | 85 | ## Changelog 86 | 87 | - 2016-10-09 Download codes from Leetcode and generate Readme 88 | - 2016-11-25 Add multi language support 89 | - 2017-01-02 Fix the bug cause by Leetcode change website: `PHPSESSID` change to `LEETCODE_SESSION` 90 | - 2017-04-22 Fix the bug cause by Leetcode change website: csrftoken encrypt, submissions change from HTML to JSON 91 | - 2018-04-02 Modify Phantomjs to Chromedriver. Add time.sleep when download otherwise would be forbidden by leetcode. 92 | - 2018-09-27 Fix the login bug caused by Leetcode change its login page -------------------------------------------------------------------------------- /config.cfg.example: -------------------------------------------------------------------------------- 1 | [leetcode] 2 | 3 | username = username 4 | password = password 5 | language = python,javascript 6 | repo = https://github.com/bonfy/leetcode 7 | driverpath = /usr/local/bin/chromedriver 8 | -------------------------------------------------------------------------------- /demo/leetcode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bonfy/leetcode/aae6fbb9198aa866937ca66e6212b090e6f5e8c6/demo/leetcode.gif -------------------------------------------------------------------------------- /leetcode_generate.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 3 | # Author: BONFY 4 | # Github: https://github.com/bonfy 5 | # Repo: https://github.com/bonfy/leetcode 6 | # Usage: Leetcode solution downloader and auto generate readme 7 | # 8 | import requests 9 | import os 10 | import configparser 11 | import json 12 | import time 13 | import datetime 14 | import re 15 | import sys 16 | import html 17 | 18 | from pathlib import Path 19 | from selenium import webdriver 20 | from collections import namedtuple, OrderedDict 21 | 22 | HOME = Path.cwd() 23 | MAX_DIGIT_LEN = 4 # 1000+ PROBLEMS 24 | SOLUTION_FOLDER_NAME = 'solutions' 25 | SOLUTION_FOLDER = Path.joinpath(HOME, SOLUTION_FOLDER_NAME) 26 | CONFIG_FILE = Path.joinpath(HOME, 'config.cfg') 27 | COOKIE_PATH = Path.joinpath(HOME, 'cookies.json') 28 | BASE_URL = 'https://leetcode.com' 29 | # If you have proxy, change PROXIES below 30 | PROXIES = None 31 | HEADERS = { 32 | 'Accept': '*/*', 33 | 'Accept-Encoding': 'gzip,deflate,sdch', 34 | 'Accept-Language': 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4', 35 | 'Connection': 'keep-alive', 36 | 'Content-Type': 'application/x-www-form-urlencoded', 37 | 'Host': 'leetcode.com', 38 | 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36', # NOQA 39 | } 40 | 41 | 42 | def get_config_from_file(): 43 | cp = configparser.ConfigParser() 44 | cp.read(CONFIG_FILE) 45 | if 'leetcode' not in list(cp.sections()): 46 | raise Exception('Please create config.cfg first.') 47 | 48 | username = cp.get('leetcode', 'username') 49 | if os.getenv('leetcode_username'): 50 | username = os.getenv('leetcode_username') 51 | password = cp.get('leetcode', 'password') 52 | if os.getenv('leetcode_password'): 53 | password = os.getenv('leetcode_password') 54 | if not username or not password: # username and password not none 55 | raise Exception( 56 | 'Please input your username and password in config.cfg.' 57 | ) 58 | 59 | language = cp.get('leetcode', 'language') 60 | if not language: 61 | language = 'python' # language default python 62 | repo = cp.get('leetcode', 'repo') 63 | if not repo: 64 | raise Exception('Please input your Github repo address') 65 | 66 | driverpath = cp.get('leetcode', 'driverpath') 67 | rst = dict( 68 | username=username, 69 | password=password, 70 | language=language.lower(), 71 | repo=repo, 72 | driverpath=driverpath, 73 | ) 74 | return rst 75 | 76 | 77 | def rep_unicode_in_code(code): 78 | """ 79 | Replace unicode to str in the code 80 | like '\u003D' to '=' 81 | :param code: type str 82 | :return: type str 83 | """ 84 | pattern = re.compile('(\\\\u[0-9a-zA-Z]{4})') 85 | m = pattern.findall(code) 86 | for item in set(m): 87 | code = code.replace(item, chr(int(item[2:], 16))) # item[2:]去掉\u 88 | return code 89 | 90 | 91 | def check_and_make_dir(dirname): 92 | p = Path(dirname) 93 | if not p.exists(): 94 | p.mkdir(parents=True) 95 | 96 | 97 | ProgLang = namedtuple('ProgLang', ['language', 'ext', 'annotation']) 98 | ProgLangList = [ 99 | ProgLang('cpp', 'cpp', '//'), 100 | ProgLang('java', 'java', '//'), 101 | ProgLang('python', 'py', '#'), 102 | ProgLang('python3', 'py', '#'), 103 | ProgLang('c', 'c', '//'), 104 | ProgLang('csharp', 'cs', '//'), 105 | ProgLang('javascript', 'js', '//'), 106 | ProgLang('ruby', 'rb', '#'), 107 | ProgLang('kotlin', 'kt', '//'), 108 | ProgLang('swift', 'swift', '//'), 109 | ProgLang('golang', 'go', '//'), 110 | ProgLang('scala', 'scala', '//'), 111 | ProgLang('rust', 'rs', '//'), 112 | ] 113 | ProgLangDict = dict((item.language, item) for item in ProgLangList) 114 | CONFIG = get_config_from_file() 115 | 116 | 117 | class QuizItem: 118 | """ QuizItem """ 119 | base_url = BASE_URL 120 | 121 | def __init__(self, **data): 122 | self.__dict__.update(data) 123 | self.solutions = [] 124 | 125 | def __str__(self): 126 | return ''.format( 127 | question_id=self.question_id, 128 | question__title_slug=self.question__title_slug, 129 | difficulty=self.difficulty, 130 | is_pass=self.is_pass, 131 | ) 132 | 133 | def __repr__(self): 134 | return self.__str__() 135 | 136 | @property 137 | def json_object(self): 138 | addition_properties = [ 139 | 'is_pass', 'difficulty', 'is_lock', 'url', 'acceptance' 140 | ] 141 | dct = self.__dict__ 142 | for prop in addition_properties: 143 | dct[prop] = getattr(self, prop) 144 | return dct 145 | 146 | @property 147 | def is_pass(self): 148 | return True if self.status == 'ac' else False 149 | 150 | @property 151 | def difficulty(self): 152 | difficulty = {1: "Easy", 2: "Medium", 3: "Hard"} 153 | return difficulty[self.level] 154 | 155 | @property 156 | def is_lock(self): 157 | return not self.is_favor and self.paid_only 158 | 159 | @property 160 | def url(self): 161 | return '{base_url}/problems/{question__title_slug}'.format( 162 | base_url=self.base_url, 163 | question__title_slug=self.question__title_slug, 164 | ) 165 | 166 | @property 167 | def acceptance(self): 168 | return '%.1f%%' % ( 169 | float(self.total_acs) * 100 / float(self.total_submitted) 170 | ) 171 | 172 | 173 | class Leetcode: 174 | 175 | def __init__(self): 176 | self.items = [] 177 | self.submissions = [] 178 | self.num_solved = 0 179 | self.num_total = 0 180 | self.num_lock = 0 181 | # change proglang to list 182 | # config set multi languages 183 | self.languages = [x.strip() for x in CONFIG['language'].split(',')] 184 | proglangs = [ 185 | ProgLangDict[x.strip()] for x in CONFIG['language'].split(',') 186 | ] 187 | self.prolangdict = dict(zip(self.languages, proglangs)) 188 | self.base_url = BASE_URL 189 | self.session = requests.Session() 190 | self.session.headers.update(HEADERS) 191 | self.session.proxies = PROXIES 192 | self.cookies = None 193 | 194 | def login(self): 195 | LOGIN_URL = self.base_url + '/accounts/login/' # NOQA 196 | if not CONFIG['username'] or not CONFIG['password']: 197 | raise Exception( 198 | 'Leetcode - Please input your username and password in config.cfg.' 199 | ) 200 | 201 | usr = CONFIG['username'] 202 | pwd = CONFIG['password'] 203 | # driver = webdriver.PhantomJS() 204 | options = webdriver.ChromeOptions() 205 | options.add_argument('headless') 206 | options.add_argument('--disable-gpu') 207 | executable_path = CONFIG.get('driverpath') 208 | driver = webdriver.Chrome( 209 | chrome_options=options, executable_path=executable_path 210 | ) 211 | driver.get(LOGIN_URL) 212 | 213 | # Wait for update 214 | time.sleep(10) 215 | 216 | driver.find_element_by_name('login').send_keys(usr) 217 | driver.find_element_by_name('password').send_keys(pwd) 218 | # driver.find_element_by_id('id_remember').click() 219 | btns = driver.find_elements_by_tag_name('button') 220 | # print(btns) 221 | submit_btn = btns[1] 222 | submit_btn.click() 223 | 224 | time.sleep(5) 225 | webdriver_cookies = driver.get_cookies() 226 | driver.close() 227 | if 'LEETCODE_SESSION' not in [ 228 | cookie['name'] for cookie in webdriver_cookies 229 | ]: 230 | raise Exception('Please check your config or your network.') 231 | 232 | with open(COOKIE_PATH, 'w') as f: 233 | json.dump(webdriver_cookies, f, indent=2) 234 | self.cookies = { 235 | str(cookie['name']): str(cookie['value']) 236 | for cookie in webdriver_cookies 237 | } 238 | self.session.cookies.update(self.cookies) 239 | 240 | def load_items_from_api(self): 241 | """ load items from api""" 242 | api_url = self.base_url + '/api/problems/algorithms/' # NOQA 243 | r = self.session.get(api_url, proxies=PROXIES) 244 | assert r.status_code == 200 245 | rst = json.loads(r.text) 246 | # make sure your user_name is not None 247 | # thus the stat_status_pairs is real 248 | if not rst['user_name']: 249 | raise Exception("Something wrong with your personal info.\n") 250 | 251 | self.items = [] # destroy first ; for sake maybe needn't 252 | self.num_solved = rst['num_solved'] 253 | self.num_total = rst['num_total'] 254 | self.items = list(self._generate_items_from_api(rst)) 255 | self.num_lock = len([i for i in self.items if i.is_lock]) 256 | self.items.reverse() 257 | 258 | def load(self): 259 | """ 260 | load: all in one 261 | 262 | login -> load api -> load submissions -> solutions to items 263 | return `all in one items` 264 | """ 265 | # if cookie is valid, get api_url twice 266 | # TODO: here can optimize 267 | if not self.is_login: 268 | self.login() 269 | self.load_items_from_api() 270 | self.load_submissions() 271 | self.load_solutions_to_items() 272 | 273 | def _generate_items_from_api(self, json_data): 274 | stat_status_pairs = json_data['stat_status_pairs'] 275 | for quiz in stat_status_pairs: 276 | if quiz['stat']['question__hide']: 277 | continue 278 | 279 | data = {} 280 | data['question__title_slug'] = quiz['stat']['question__title_slug'] 281 | data['question__title'] = quiz['stat']['question__title'] 282 | data['question__article__slug'] = quiz['stat'][ 283 | 'question__article__slug' 284 | ] 285 | # data['is_paid'] = json_data['is_paid'] 286 | data['paid_only'] = quiz['paid_only'] 287 | data['level'] = quiz['difficulty']['level'] 288 | data['is_favor'] = quiz['is_favor'] 289 | data['total_acs'] = quiz['stat']['total_acs'] 290 | data['total_submitted'] = quiz['stat']['total_submitted'] 291 | data['question_id'] = quiz['stat']['question_id'] 292 | data['status'] = quiz['status'] 293 | item = QuizItem(**data) 294 | yield item 295 | 296 | @property 297 | def is_login(self): 298 | """ validate if the cookie exists and not overtime """ 299 | api_url = self.base_url + '/api/problems/algorithms/' # NOQA 300 | if not COOKIE_PATH.exists(): 301 | return False 302 | 303 | with open(COOKIE_PATH, 'r') as f: 304 | webdriver_cookies = json.load(f) 305 | self.cookies = { 306 | str(cookie['name']): str(cookie['value']) 307 | for cookie in webdriver_cookies 308 | } 309 | self.session.cookies.update(self.cookies) 310 | r = self.session.get(api_url, proxies=PROXIES) 311 | if r.status_code != 200: 312 | return False 313 | 314 | data = json.loads(r.text) 315 | return 'user_name' in data and data['user_name'] != '' 316 | 317 | def load_submissions(self): 318 | """ load all submissions from leetcode """ 319 | # set limit a big num 320 | print('API load submissions request 2 seconds per request') 321 | print('Please wait ...') 322 | limit = 20 323 | offset = 0 324 | last_key = '' 325 | while True: 326 | print('try to load submissions from ', offset, ' to ', offset+limit) 327 | submissions_url = '{}/api/submissions/?format=json&limit={}&offset={}&last_key={}'.format( 328 | self.base_url, limit, offset, last_key 329 | ) 330 | 331 | resp = self.session.get(submissions_url, proxies=PROXIES) 332 | # print(submissions_url, ':', resp.status_code) 333 | assert resp.status_code == 200 334 | data = resp.json() 335 | if 'has_next' not in data.keys(): 336 | raise Exception('Get submissions wrong, Check network\n') 337 | 338 | self.submissions += data['submissions_dump'] 339 | if data['has_next']: 340 | offset += limit 341 | last_key = data['last_key'] 342 | # print('last_key:', last_key) 343 | time.sleep(2.5) 344 | else: 345 | break 346 | 347 | def load_solutions_to_items(self): 348 | """ 349 | load all solutions to items 350 | 351 | combine submission's `runtime` `title` `lang` `submission_url` to items 352 | """ 353 | titles = [i.question__title for i in self.items] 354 | itemdict = OrderedDict(zip(titles, self.items)) 355 | 356 | def make_sub(sub): 357 | return dict( 358 | runtime=int(sub['runtime'][:-3]), 359 | title=sub['title'], 360 | lang=sub['lang'], 361 | submission_url=self.base_url + sub['url'], 362 | ) 363 | 364 | ac_subs = [ 365 | make_sub(sub) 366 | for sub in self.submissions 367 | if sub['status_display'] == 'Accepted' 368 | ] 369 | 370 | def remain_shortesttime_submissions(submissions): 371 | submissions_dict = {} 372 | for item in submissions: 373 | k = '{}-{}'.format(item['lang'], item['title']) 374 | if k not in submissions_dict.keys(): 375 | submissions_dict[k] = item 376 | else: 377 | old = submissions_dict[k] 378 | if item['runtime'] < old['runtime']: 379 | submissions_dict[k] = item 380 | return list(submissions_dict.values()) 381 | 382 | shortest_subs = remain_shortesttime_submissions(ac_subs) 383 | for solution in shortest_subs: 384 | title = solution['title'] 385 | if title in itemdict.keys(): 386 | itemdict[title].solutions.append(solution) 387 | 388 | def _get_code_by_solution(self, solution): 389 | """ 390 | get code by solution 391 | 392 | solution: type dict 393 | """ 394 | solution_url = solution['submission_url'] 395 | print(solution_url) 396 | r = self.session.get(solution_url, proxies=PROXIES) 397 | assert r.status_code == 200 398 | pattern = re.compile( 399 | r'.*)\" />\n \n .*)\',\n editCodeUrl', re.S 415 | ) 416 | m1 = pattern.search(r.text) 417 | code = m1.groupdict()['code'] if m1 else None 418 | if not code: 419 | raise Exception( 420 | 'Can not find solution code in question:{title}'.format( 421 | title=solution['title'] 422 | ) 423 | ) 424 | 425 | code = rep_unicode_in_code(code) 426 | return question, code 427 | 428 | def _get_code_with_anno(self, solution): 429 | question, code = self._get_code_by_solution(solution) 430 | language = solution['lang'] 431 | # generate question with anno 432 | lines = [] 433 | for line in question.split('\n'): 434 | if line.strip() == '': 435 | lines.append(self.prolangdict[language].annotation) 436 | else: 437 | lines.append( 438 | '{anno} {line}'.format( 439 | anno=self.prolangdict[language].annotation, 440 | line=html.unescape(line), 441 | ) 442 | ) 443 | quote_question = '\n'.join(lines) 444 | # generate content 445 | content = '# -*- coding:utf-8 -*-' + '\n' * 3 if language == 'python' else '' 446 | content += quote_question 447 | content += '\n' * 3 448 | content += code 449 | content += '\n' 450 | return content 451 | 452 | def _download_code_by_quiz(self, quiz): 453 | """ 454 | Download code by quiz 455 | quiz: type QuizItem 456 | """ 457 | qid = quiz.question_id 458 | qtitle = quiz.question__title_slug 459 | slts = list( 460 | filter(lambda i: i['lang'] in self.languages, quiz.solutions) 461 | ) 462 | if not slts: 463 | print( 464 | 'No solution with the set languages in question:{}-{}'.format( 465 | qid, qtitle 466 | ) 467 | ) 468 | return 469 | 470 | qname = '{id}-{title}'.format(id=str(qid).zfill(MAX_DIGIT_LEN), title=qtitle) 471 | print('begin download ' + qname) 472 | path = Path.joinpath(SOLUTION_FOLDER, qname) 473 | check_and_make_dir(path) 474 | for slt in slts: 475 | fname = '{title}.{ext}'.format( 476 | title=qtitle, ext=self.prolangdict[slt['lang']].ext 477 | ) 478 | filename = Path.joinpath(path, fname) 479 | content = self._get_code_with_anno(slt) 480 | import codecs 481 | 482 | with codecs.open(filename, 'w', 'utf-8') as f: 483 | print('write to file ->', fname) 484 | f.write(content) 485 | 486 | def _find_item_by_quiz_id(self, qid): 487 | """ 488 | find the item by quiz id 489 | """ 490 | lst = list(filter(lambda x: x.question_id == qid, self.items)) 491 | if len(lst) == 1: 492 | return lst[0] 493 | 494 | print('No exits quiz id:', qid) 495 | 496 | def download_by_id(self, qid): 497 | quiz = self._find_item_by_quiz_id(qid) 498 | if quiz: 499 | self._download_code_by_quiz(quiz) 500 | 501 | def download(self): 502 | """ download all solutions with single thread """ 503 | ac_items = [i for i in self.items if i.is_pass] 504 | for quiz in ac_items: 505 | time.sleep(1) 506 | self._download_code_by_quiz(quiz) 507 | 508 | def download_with_thread_pool(self): 509 | """ download all solutions with multi thread """ 510 | ac_items = [i for i in self.items if i.is_pass] 511 | from concurrent.futures import ThreadPoolExecutor 512 | 513 | pool = ThreadPoolExecutor(max_workers=4) 514 | for quiz in ac_items: 515 | pool.submit(self._download_code_by_quiz, quiz) 516 | pool.shutdown(wait=True) 517 | 518 | def write_readme(self): 519 | """Write Readme to current folder""" 520 | languages_readme = ','.join([x.capitalize() for x in self.languages]) 521 | md = '''# :pencil2: Leetcode Solutions with {language} 522 | Update time: {tm} 523 | 524 | Auto created by [leetcode_generate](https://github.com/bonfy/leetcode) 525 | 526 | I have solved **{num_solved} / {num_total}** problems 527 | while there are **{num_lock}** problems still locked. 528 | 529 | If you want to use this tool please follow this [Usage Guide](https://github.com/bonfy/leetcode/blob/master/README_leetcode_generate.md) 530 | 531 | If you have any question, please give me an [issue]({repo}/issues). 532 | 533 | If you are loving solving problems in leetcode, please contact me to enjoy it together! 534 | 535 | (Notes: :lock: means you need to buy a book from Leetcode to unlock the problem) 536 | 537 | | # | Title | Source Code | Article | Difficulty | 538 | |:---:|:---:|:---:|:---:|:---:|'''.format( 539 | language=languages_readme, 540 | tm=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 541 | num_solved=self.num_solved, 542 | num_total=self.num_total, 543 | num_lock=self.num_lock, 544 | repo=CONFIG['repo'], 545 | ) 546 | md += '\n' 547 | for item in self.items: 548 | article = '' 549 | if item.question__article__slug: 550 | article = '[:memo:](https://leetcode.com/articles/{article}/)'.format( 551 | article=item.question__article__slug 552 | ) 553 | if item.is_lock: 554 | language = ':lock:' 555 | else: 556 | if item.solutions: 557 | dirname = '{folder}/{id}-{title}'.format( 558 | folder=SOLUTION_FOLDER_NAME, 559 | id=str(item.question_id).zfill(MAX_DIGIT_LEN), 560 | title=item.question__title_slug, 561 | ) 562 | language = '' 563 | language_lst = [ 564 | i['lang'] 565 | for i in item.solutions 566 | if i['lang'] in self.languages 567 | ] 568 | while language_lst: 569 | lan = language_lst.pop() 570 | language += '[{language}]({repo}/blob/master/{dirname}/{title}.{ext})'.format( 571 | language=lan.capitalize(), 572 | repo=CONFIG['repo'], 573 | dirname=dirname, 574 | title=item.question__title_slug, 575 | ext=self.prolangdict[lan].ext, 576 | ) 577 | language += ' ' 578 | else: 579 | language = '' 580 | language = language.strip() 581 | md += '|{id}|[{title}]({url})|{language}|{article}|{difficulty}|\n'.format( 582 | id=item.question_id, 583 | title=item.question__title_slug, 584 | url=item.url, 585 | language=language, 586 | article=article, 587 | difficulty=item.difficulty, 588 | ) 589 | with open('README.md', 'w') as f: 590 | f.write(md) 591 | 592 | def push_to_github(self): 593 | strdate = datetime.datetime.now().strftime('%Y-%m-%d') 594 | cmd_git_add = 'git add .' 595 | cmd_git_commit = 'git commit -m "update at {date}"'.format( 596 | date=strdate 597 | ) 598 | cmd_git_push = 'git push -u origin master' 599 | os.system(cmd_git_add) 600 | os.system(cmd_git_commit) 601 | os.system(cmd_git_push) 602 | 603 | 604 | def do_job(leetcode): 605 | leetcode.load() 606 | print('Leetcode load self info') 607 | if len(sys.argv) == 1: 608 | # simple download 609 | # leetcode.dowload() 610 | # we use multi thread 611 | print('download all leetcode solutions') 612 | # leetcode.download_with_thread_pool() 613 | leetcode.download() 614 | else: 615 | for qid in sys.argv[1:]: 616 | print('begin leetcode by id: {id}'.format(id=qid)) 617 | leetcode.download_by_id(int(qid)) 618 | print('Leetcode finish dowload') 619 | leetcode.write_readme() 620 | print('Leetcode finish write readme') 621 | leetcode.push_to_github() 622 | print('push to github') 623 | 624 | 625 | if __name__ == '__main__': 626 | leetcode = Leetcode() 627 | while True: 628 | do_job(leetcode) 629 | time.sleep(24 * 60 * 60) 630 | -------------------------------------------------------------------------------- /req.txt: -------------------------------------------------------------------------------- 1 | certifi==2018.1.18 2 | chardet==3.0.4 3 | cssselect==1.0.3 4 | idna==2.6 5 | lxml==4.2.1 6 | pyquery==1.4.0 7 | requests==2.21.0 8 | selenium==3.11.0 9 | urllib3==1.24.1 10 | -------------------------------------------------------------------------------- /solutions/0001-two-sum/two-sum.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array of integers, return indices of the two numbers such that they add up to a specific target. 5 | # 6 | # You may assume that each input would have exactly one solution, and you may not use the same element twice. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Given nums = [2, 7, 11, 15], target = 9, 12 | # 13 | # Because nums[0] + nums[1] = 2 + 7 = 9, 14 | # return [0, 1]. 15 | # 16 | # 17 | 18 | 19 | class Solution(object): 20 | def twoSum(self, nums, target): 21 | """ 22 | :type nums: List[int] 23 | :type target: int 24 | :rtype: List[int] 25 | """ 26 | d = {} 27 | for i, v in enumerate(nums): 28 | if v in d: 29 | return [d[v],i] 30 | d[target-v] = i 31 | 32 | -------------------------------------------------------------------------------- /solutions/0001-two-sum/two-sum.rs: -------------------------------------------------------------------------------- 1 | // Given an array of integers, return indices of the two numbers such that they add up to a specific target. 2 | // 3 | // You may assume that each input would have exactly one solution, and you may not use the same element twice. 4 | // 5 | // Example: 6 | // 7 | // 8 | // Given nums = [2, 7, 11, 15], target = 9, 9 | // 10 | // Because nums[0] + nums[1] = 2 + 7 = 9, 11 | // return [0, 1]. 12 | // 13 | // 14 | 15 | 16 | use std::collections::HashMap; 17 | 18 | impl Solution { 19 | pub fn two_sum(nums: &mut Vec, target: i32) -> Vec { 20 | let mut seen = HashMap::new(); 21 | for (i, num) in nums.iter().enumerate() { 22 | if seen.contains_key(num) { 23 | return vec![seen[num] as i32, i as i32]; 24 | } else { seen.insert(target - num, i); } 25 | } 26 | vec![] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /solutions/0002-add-two-numbers/add-two-numbers.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. 5 | # 6 | # You may assume the two numbers do not contain any leading zero, except the number 0 itself. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 12 | # Output: 7 -> 0 -> 8 13 | # Explanation: 342 + 465 = 807. 14 | # 15 | # 16 | 17 | 18 | # Definition for singly-linked list. 19 | 20 | # class ListNode(object): 21 | # def __init__(self, x): 22 | # self.val = x 23 | # self.next = None 24 | 25 | class Solution(object): 26 | def addTwoNumbers(self, l1, l2): 27 | """ 28 | :type l1: ListNode 29 | :type l2: ListNode 30 | :rtype: ListNode 31 | """ 32 | if(l1 is None and l2 is None): 33 | return None 34 | 35 | head = ListNode(0) 36 | point = head 37 | carry = 0 38 | while l1 is not None and l2 is not None: 39 | s = carry + l1.val + l2.val 40 | point.next = ListNode(s % 10) 41 | carry = s / 10 42 | l1 = l1.next 43 | l2 = l2.next 44 | point = point.next 45 | 46 | while l1 is not None: 47 | s = carry + l1.val 48 | point.next = ListNode(s % 10) 49 | carry = s / 10 50 | l1 = l1.next 51 | point = point.next 52 | 53 | while l2 is not None: 54 | s = carry + l2.val 55 | point.next = ListNode(s % 10) 56 | carry = s / 10 57 | l2 = l2.next 58 | point = point.next 59 | 60 | if carry != 0: 61 | point.next = ListNode(carry) 62 | 63 | return head.next 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /solutions/0003-longest-substring-without-repeating-characters/longest-substring-without-repeating-characters.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string, find the length of the longest substring without repeating characters. 5 | # 6 | # 7 | # Example 1: 8 | # 9 | # 10 | # Input: "abcabcbb" 11 | # Output: 3 12 | # Explanation: The answer is "abc", with the length of 3. 13 | # 14 | # 15 | # 16 | # Example 2: 17 | # 18 | # 19 | # Input: "bbbbb" 20 | # Output: 1 21 | # Explanation: The answer is "b", with the length of 1. 22 | # 23 | # 24 | # 25 | # Example 3: 26 | # 27 | # 28 | # Input: "pwwkew" 29 | # Output: 3 30 | # Explanation: The answer is "wke", with the length of 3. 31 | # Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 32 | # 33 | # 34 | # 35 | # 36 | # 37 | 38 | 39 | class Solution(object): 40 | def lengthOfLongestSubstring(self, s): 41 | """ 42 | :type s: str 43 | :rtype: int 44 | """ 45 | 46 | longest, start, visited = 0, 0, [False for _ in range(256)] 47 | for ind, val in enumerate(s): 48 | if not visited[ord(val)]: 49 | visited[ord(val)] = True 50 | else: 51 | while val != s[start]: 52 | visited[ord(s[start])] = False 53 | start += 1 54 | start += 1 55 | longest = max(longest, ind - start + 1) 56 | return longest 57 | 58 | -------------------------------------------------------------------------------- /solutions/0004-median-of-two-sorted-arrays/median-of-two-sorted-arrays.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # There are two sorted arrays nums1 and nums2 of size m and n respectively. 5 | # 6 | # Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 7 | # 8 | # You may assume nums1 and nums2 cannot be both empty. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # nums1 = [1, 3] 14 | # nums2 = [2] 15 | # 16 | # The median is 2.0 17 | # 18 | # 19 | # Example 2: 20 | # 21 | # 22 | # nums1 = [1, 2] 23 | # nums2 = [3, 4] 24 | # 25 | # The median is (2 + 3)/2 = 2.5 26 | # 27 | # 28 | 29 | 30 | class Solution(object): 31 | def findMedianSortedArrays(self, nums1, nums2): 32 | """ 33 | :type nums1: List[int] 34 | :type nums2: List[int] 35 | :rtype: float 36 | """ 37 | nums = sorted(nums1 + nums2) 38 | t_len = len(nums) 39 | if t_len == 1: 40 | return nums[0] 41 | 42 | if t_len % 2: 43 | return nums[t_len/2] 44 | else: 45 | return (nums[t_len/2] + nums[t_len/2 -1]) /2.0 46 | -------------------------------------------------------------------------------- /solutions/0005-longest-palindromic-substring/longest-palindromic-substring.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: "babad" 10 | # Output: "bab" 11 | # Note: "aba" is also a valid answer. 12 | # 13 | # 14 | # Example 2: 15 | # 16 | # 17 | # Input: "cbbd" 18 | # Output: "bb" 19 | # 20 | # 21 | 22 | 23 | class Solution(object): 24 | def longestPalindrome(self, s): 25 | """ 26 | :type s: str 27 | :rtype: str 28 | """ 29 | longest, mid = "", (len(s) - 1) / 2 30 | i, j = mid, mid 31 | while i >= 0 and j < len(s): 32 | args = [(s, i, i), (s, i, i + 1), (s, j, j), (s, j, j + 1)] 33 | for arg in args: 34 | tmp = self.longestPalindromeByAxis(*arg) 35 | if len(tmp) > len(longest): 36 | longest = tmp 37 | if len(longest) >= i * 2: 38 | if len(longest) == 1: 39 | return s[0] 40 | return longest 41 | i, j = i - 1, j + 1 42 | return longest 43 | 44 | def longestPalindromeByAxis(self, s, left, right): 45 | while left >= 0 and right < len(s) and s[left] == s[right]: 46 | left, right = left - 1, right + 1 47 | return s[left + 1: right] 48 | -------------------------------------------------------------------------------- /solutions/0006-zigzag-conversion/zigzag-conversion.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) 5 | # 6 | # 7 | # P A H N 8 | # A P L S I I G 9 | # Y I R 10 | # 11 | # 12 | # And then read line by line: "PAHNAPLSIIGYIR" 13 | # 14 | # Write the code that will take a string and make this conversion given a number of rows: 15 | # 16 | # 17 | # string convert(string s, int numRows); 18 | # 19 | # Example 1: 20 | # 21 | # 22 | # Input: s = "PAYPALISHIRING", numRows = 3 23 | # Output: "PAHNAPLSIIGYIR" 24 | # 25 | # 26 | # Example 2: 27 | # 28 | # 29 | # Input: s = "PAYPALISHIRING", numRows = 4 30 | # Output: "PINALSIGYAHRPI" 31 | # Explanation: 32 | # 33 | # P I N 34 | # A L S I G 35 | # Y A H R 36 | # P I 37 | # 38 | 39 | 40 | class Solution(object): 41 | def convert(self, s, numRows): 42 | """ 43 | :type s: str 44 | :type numRows: int 45 | :rtype: str 46 | """ 47 | if not s or len(s) == 0 or numRows <= 0: 48 | return "" 49 | if numRows == 1: 50 | return s 51 | if len(s) % (numRows + numRows - 2): 52 | s = s + '#' * (numRows + numRows - 2 - (len(s) % (numRows + numRows - 2))) 53 | blocks = len(s)/(numRows + numRows - 2) 54 | res = '' 55 | for i in range(numRows): 56 | for j in range(blocks): 57 | if i == 0 or i == numRows-1: 58 | res += s[i + j*(numRows + numRows - 2)] 59 | else: 60 | res += s[i + j*(numRows + numRows - 2)] 61 | res += s[2*numRows-2-i + j*(numRows + numRows - 2)] 62 | return ''.join(res.split('#')) 63 | 64 | -------------------------------------------------------------------------------- /solutions/0007-reverse-integer/reverse-integer.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a 32-bit signed integer, reverse digits of an integer. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 123 10 | # Output: 321 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: -123 17 | # Output: -321 18 | # 19 | # 20 | # Example 3: 21 | # 22 | # 23 | # Input: 120 24 | # Output: 21 25 | # 26 | # 27 | # Note: 28 | # Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 29 | # 30 | 31 | 32 | class Solution(object): 33 | def reverse(self, x): 34 | """ 35 | :type x: int 36 | :rtype: int 37 | """ 38 | l = list(str(abs(x))) 39 | l.reverse() 40 | rst = int(''.join(l)) 41 | if rst > 2147483647: 42 | return 0 43 | else: 44 | return rst if x>=0 else rst * (-1) 45 | 46 | 47 | -------------------------------------------------------------------------------- /solutions/0008-string-to-integer-atoi/string-to-integer-atoi.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Implement atoi which converts a string to an integer. 5 | # 6 | # The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. 7 | # 8 | # The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. 9 | # 10 | # If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. 11 | # 12 | # If no valid conversion could be performed, a zero value is returned. 13 | # 14 | # Note: 15 | # 16 | # 17 | # Only the space character ' ' is considered as whitespace character. 18 | # Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. If the numerical value is out of the range of representable values, INT_MAX (231 − 1) or INT_MIN (−231) is returned. 19 | # 20 | # 21 | # Example 1: 22 | # 23 | # 24 | # Input: "42" 25 | # Output: 42 26 | # 27 | # 28 | # Example 2: 29 | # 30 | # 31 | # Input: " -42" 32 | # Output: -42 33 | # Explanation: The first non-whitespace character is '-', which is the minus sign. 34 | #   Then take as many numerical digits as possible, which gets 42. 35 | # 36 | # 37 | # Example 3: 38 | # 39 | # 40 | # Input: "4193 with words" 41 | # Output: 4193 42 | # Explanation: Conversion stops at digit '3' as the next character is not a numerical digit. 43 | # 44 | # 45 | # Example 4: 46 | # 47 | # 48 | # Input: "words and 987" 49 | # Output: 0 50 | # Explanation: The first non-whitespace character is 'w', which is not a numerical 51 | #   digit or a +/- sign. Therefore no valid conversion could be performed. 52 | # 53 | # Example 5: 54 | # 55 | # 56 | # Input: "-91283472332" 57 | # Output: -2147483648 58 | # Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer. 59 | #   Thefore INT_MIN (−231) is returned. 60 | # 61 | 62 | 63 | class Solution(object): 64 | def myAtoi(self, str): 65 | """ 66 | :type str: str 67 | :rtype: int 68 | """ 69 | import re 70 | p = re.compile(r'^[+-]?[0-9]+') 71 | m = re.match(p, str.strip()) 72 | if m: 73 | ret = int(m.group()) 74 | if ret < -0x80000000: 75 | return -0x80000000 76 | elif ret > 0x7fffffff: 77 | return 0x7fffffff 78 | return ret 79 | else: 80 | return 0 81 | 82 | -------------------------------------------------------------------------------- /solutions/0009-palindrome-number/palindrome-number.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 121 10 | # Output: true 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: -121 17 | # Output: false 18 | # Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome. 19 | # 20 | # 21 | # Example 3: 22 | # 23 | # 24 | # Input: 10 25 | # Output: false 26 | # Explanation: Reads 01 from right to left. Therefore it is not a palindrome. 27 | # 28 | # 29 | # Follow up: 30 | # 31 | # Coud you solve it without converting the integer to a string? 32 | # 33 | 34 | 35 | class Solution(object): 36 | def isPalindrome(self, x): 37 | """ 38 | :type x: int 39 | :rtype: bool 40 | """ 41 | if x < 0: 42 | return False 43 | x = abs(x) 44 | l = len(str(x)) 45 | i = 1 46 | while i < l / 2 + 1: 47 | 48 | head = (x / 10 ** (l-i)) % 10 49 | tail = (x % 10 ** i) if i == 1 else (x % 10 ** i) / (10 ** (i-1)) 50 | if head != tail: 51 | return False 52 | i = i + 1 53 | 54 | return True 55 | -------------------------------------------------------------------------------- /solutions/0010-regular-expression-matching/regular-expression-matching.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'. 5 | # 6 | # 7 | # '.' Matches any single character. 8 | # '*' Matches zero or more of the preceding element. 9 | # 10 | # 11 | # The matching should cover the entire input string (not partial). 12 | # 13 | # Note: 14 | # 15 | # 16 | # s could be empty and contains only lowercase letters a-z. 17 | # p could be empty and contains only lowercase letters a-z, and characters like . or *. 18 | # 19 | # 20 | # Example 1: 21 | # 22 | # 23 | # Input: 24 | # s = "aa" 25 | # p = "a" 26 | # Output: false 27 | # Explanation: "a" does not match the entire string "aa". 28 | # 29 | # 30 | # Example 2: 31 | # 32 | # 33 | # Input: 34 | # s = "aa" 35 | # p = "a*" 36 | # Output: true 37 | # Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa". 38 | # 39 | # 40 | # Example 3: 41 | # 42 | # 43 | # Input: 44 | # s = "ab" 45 | # p = ".*" 46 | # Output: true 47 | # Explanation: ".*" means "zero or more (*) of any character (.)". 48 | # 49 | # 50 | # Example 4: 51 | # 52 | # 53 | # Input: 54 | # s = "aab" 55 | # p = "c*a*b" 56 | # Output: true 57 | # Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab". 58 | # 59 | # 60 | # Example 5: 61 | # 62 | # 63 | # Input: 64 | # s = "mississippi" 65 | # p = "mis*is*p*." 66 | # Output: false 67 | # 68 | # 69 | 70 | 71 | class Solution(object): 72 | def isMatch(self, s, p): 73 | """ 74 | :type s: str 75 | :type p: str 76 | :rtype: bool 77 | """ 78 | result = [[False for j in xrange(len(p) + 1)] for i in xrange(len(s) + 1)] 79 | 80 | result[0][0] = True 81 | for i in xrange(2, len(p) + 1): 82 | if p[i-1] == '*': 83 | result[0][i] = result[0][i-2] 84 | 85 | for i in xrange(1,len(s) + 1): 86 | for j in xrange(1, len(p) + 1): 87 | if p[j-1] != '*': 88 | result[i][j] = result[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '.') 89 | else: 90 | result[i][j] = result[i][j-2] or (result[i-1][j] and (s[i-1] == p[j-2] or p[j-2] == '.')) 91 | 92 | return result[len(s)][len(p)] 93 | -------------------------------------------------------------------------------- /solutions/0011-container-with-most-water/container-with-most-water.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. 5 | # 6 | # Note: You may not slant the container and n is at least 2. 7 | # 8 | #   9 | # 10 | # 11 | # 12 | # The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49. 13 | # 14 | #   15 | # 16 | # Example: 17 | # 18 | # 19 | # Input: [1,8,6,2,5,4,8,3,7] 20 | # Output: 49 21 | # 22 | 23 | 24 | class Solution(object): 25 | def maxArea(self, height): 26 | """ 27 | :type height: List[int] 28 | :rtype: int 29 | """ 30 | max_area, i, j = 0, 0, len(height) - 1 31 | while i < j: 32 | max_area = max(max_area, min(height[i], height[j]) * (j - i)) 33 | if height[i] < height[j]: 34 | i += 1 35 | else: 36 | j -= 1 37 | return max_area 38 | 39 | -------------------------------------------------------------------------------- /solutions/0012-integer-to-roman/integer-to-roman.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. 5 | # 6 | # 7 | # Symbol Value 8 | # I 1 9 | # V 5 10 | # X 10 11 | # L 50 12 | # C 100 13 | # D 500 14 | # M 1000 15 | # 16 | # For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. 17 | # 18 | # Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: 19 | # 20 | # 21 | # I can be placed before V (5) and X (10) to make 4 and 9.  22 | # X can be placed before L (50) and C (100) to make 40 and 90.  23 | # C can be placed before D (500) and M (1000) to make 400 and 900. 24 | # 25 | # 26 | # Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. 27 | # 28 | # Example 1: 29 | # 30 | # 31 | # Input: 3 32 | # Output: "III" 33 | # 34 | # Example 2: 35 | # 36 | # 37 | # Input: 4 38 | # Output: "IV" 39 | # 40 | # Example 3: 41 | # 42 | # 43 | # Input: 9 44 | # Output: "IX" 45 | # 46 | # Example 4: 47 | # 48 | # 49 | # Input: 58 50 | # Output: "LVIII" 51 | # Explanation: L = 50, V = 5, III = 3. 52 | # 53 | # 54 | # Example 5: 55 | # 56 | # 57 | # Input: 1994 58 | # Output: "MCMXCIV" 59 | # Explanation: M = 1000, CM = 900, XC = 90 and IV = 4. 60 | # 61 | 62 | 63 | class Solution(object): 64 | def intToRoman(self, num): 65 | """ 66 | :type num: int 67 | :rtype: str 68 | """ 69 | int2roman = { 70 | 1: "I", 71 | 4: "IV", 72 | 5: "V", 73 | 9: "IX", 74 | 75 | 10: "X", 76 | 40: "XL", 77 | 50: "L", 78 | 90: "XC", 79 | 80 | 100: "C", 81 | 400: "CD", 82 | 500: "D", 83 | 900: "CM", 84 | 85 | 1000: "M" 86 | } 87 | 88 | builder = [] 89 | components = [1, 4, 5, 9, 10, 10, 40, 50, 90, 100, 400, 500, 900, 1000] 90 | for item in reversed(components): 91 | while num >= item: 92 | builder.append(int2roman[item]) 93 | num -= item 94 | return "".join(builder) 95 | -------------------------------------------------------------------------------- /solutions/0013-roman-to-integer/roman-to-integer.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. 5 | # 6 | # 7 | # Symbol Value 8 | # I 1 9 | # V 5 10 | # X 10 11 | # L 50 12 | # C 100 13 | # D 500 14 | # M 1000 15 | # 16 | # For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. 17 | # 18 | # Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: 19 | # 20 | # 21 | # I can be placed before V (5) and X (10) to make 4 and 9.  22 | # X can be placed before L (50) and C (100) to make 40 and 90.  23 | # C can be placed before D (500) and M (1000) to make 400 and 900. 24 | # 25 | # 26 | # Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 27 | # 28 | # Example 1: 29 | # 30 | # 31 | # Input: "III" 32 | # Output: 3 33 | # 34 | # Example 2: 35 | # 36 | # 37 | # Input: "IV" 38 | # Output: 4 39 | # 40 | # Example 3: 41 | # 42 | # 43 | # Input: "IX" 44 | # Output: 9 45 | # 46 | # Example 4: 47 | # 48 | # 49 | # Input: "LVIII" 50 | # Output: 58 51 | # Explanation: L = 50, V= 5, III = 3. 52 | # 53 | # 54 | # Example 5: 55 | # 56 | # 57 | # Input: "MCMXCIV" 58 | # Output: 1994 59 | # Explanation: M = 1000, CM = 900, XC = 90 and IV = 4. 60 | # 61 | 62 | 63 | class Solution(object): 64 | def romanToInt(self, s): 65 | """ 66 | :type s: str 67 | :rtype: int 68 | """ 69 | roman = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000} 70 | total = 0 71 | for index in range(len(s)-1): 72 | type = 1 if roman[s[index]]>=roman[s[index+1]] else -1 73 | total += type*roman[s[index]] 74 | return total + roman[s[len(s)-1]] 75 | -------------------------------------------------------------------------------- /solutions/0014-longest-common-prefix/longest-common-prefix.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write a function to find the longest common prefix string amongst an array of strings. 5 | # 6 | # If there is no common prefix, return an empty string "". 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: ["flower","flow","flight"] 12 | # Output: "fl" 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: ["dog","racecar","car"] 19 | # Output: "" 20 | # Explanation: There is no common prefix among the input strings. 21 | # 22 | # 23 | # Note: 24 | # 25 | # All given inputs are in lowercase letters a-z. 26 | # 27 | 28 | 29 | class Solution(object): 30 | def longestCommonPrefix(self, strs): 31 | """ 32 | :type strs: List[str] 33 | :rtype: str 34 | """ 35 | if not strs: 36 | return "" 37 | if len(strs) == 1: 38 | return strs[0] 39 | 40 | p = strs[0] 41 | idx, rest = 0, strs[1:] 42 | while len(p) > 0: 43 | while idx < len(rest) and len(p) <= len(rest[idx]) and p == rest[idx][:len(p)]: 44 | idx += 1 45 | if idx == len(rest): 46 | return p 47 | p = p[:-1] 48 | return "" 49 | 50 | -------------------------------------------------------------------------------- /solutions/0015-3sum/3sum.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero. 5 | # 6 | # Note: 7 | # 8 | # The solution set must not contain duplicate triplets. 9 | # 10 | # Example: 11 | # 12 | # 13 | # Given array nums = [-1, 0, 1, 2, -1, -4], 14 | # 15 | # A solution set is: 16 | # [ 17 | # [-1, 0, 1], 18 | # [-1, -1, 2] 19 | # ] 20 | # 21 | # 22 | 23 | 24 | class Solution(object): 25 | def threeSum(self, nums): 26 | """ 27 | :type nums: List[int] 28 | :rtype: List[List[int]] 29 | """ 30 | nums.sort() 31 | res = [] 32 | 33 | for i in range(len(nums)-1): # because sums of 3 numbers 34 | if i == 0 or i > 0 and nums[i-1] != nums[i]: 35 | # avoid duplicate triplets [1 ,1, 1, -2] 36 | left = i + 1 37 | right = len(nums) - 1 38 | while left < right: # two-way pointer 39 | s = nums[i] + nums[left] + nums[right] 40 | if s == 0: 41 | res.append([nums[i], nums[left], nums[right]]) 42 | left += 1 43 | right -= 1 44 | while left < right and nums[left] == nums[left - 1]: 45 | left += 1 46 | while right > left and nums[right] == nums[right + 1]: 47 | right -= 1 48 | elif s < 0: 49 | left += 1 50 | else: 51 | right -= 1 52 | return res 53 | -------------------------------------------------------------------------------- /solutions/0016-3sum-closest/3sum-closest.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Given array nums = [-1, 2, 1, -4], and target = 1. 10 | # 11 | # The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). 12 | # 13 | # 14 | 15 | 16 | class Solution(object): 17 | def threeSumClosest(self, nums, target): 18 | """ 19 | :type nums: List[int] 20 | :type target: int 21 | :rtype: int 22 | """ 23 | nums.sort() 24 | result = sum(nums[:3]) 25 | for i in range(len(nums) - 2): 26 | j, k = i+1, len(nums) - 1 27 | while j < k: 28 | s = nums[i] + nums[j] + nums[k] 29 | if s == target: 30 | return s 31 | 32 | if abs(s - target) < abs(result - target): 33 | result = s 34 | 35 | if s < target: 36 | j += 1 37 | elif s > target: 38 | k -= 1 39 | return result 40 | -------------------------------------------------------------------------------- /solutions/0017-letter-combinations-of-a-phone-number/letter-combinations-of-a-phone-number.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. 5 | # 6 | # A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters. 7 | # 8 | # 9 | # 10 | # Example: 11 | # 12 | # 13 | # Input: "23" 14 | # Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 15 | # 16 | # 17 | # Note: 18 | # 19 | # Although the above answer is in lexicographical order, your answer could be in any order you want. 20 | # 21 | 22 | 23 | class Solution(object): 24 | def letterCombinations(self, digits): 25 | """ 26 | :type digits: str 27 | :rtype: List[str] 28 | """ 29 | l = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz'] 30 | end = [''] 31 | rst = [] 32 | d = digits 33 | 34 | while len(d): 35 | f = int(d[-1]) 36 | lst_f = list(l[f]) 37 | rst = [''.join([i, j]) for i in lst_f for j in end] 38 | end = rst 39 | d = d[:-1] 40 | return rst 41 | 42 | -------------------------------------------------------------------------------- /solutions/0018-4sum/4sum.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target. 5 | # 6 | # Note: 7 | # 8 | # The solution set must not contain duplicate quadruplets. 9 | # 10 | # Example: 11 | # 12 | # 13 | # Given array nums = [1, 0, -1, 0, -2, 2], and target = 0. 14 | # 15 | # A solution set is: 16 | # [ 17 | # [-1, 0, 0, 1], 18 | # [-2, -1, 1, 2], 19 | # [-2, 0, 0, 2] 20 | # ] 21 | # 22 | # 23 | 24 | 25 | class Solution(object): 26 | def fourSum(self, nums, target): 27 | """ 28 | :type nums: List[int] 29 | :type target: int 30 | :rtype: List[List[int]] 31 | """ 32 | def findNsum(nums, target, N, result, results): 33 | if len(nums) < N or N < 2 or target < nums[0]*N or target > nums[-1]*N: # early termination 34 | return 35 | if N == 2: # two pointers solve sorted 2-sum problem 36 | l,r = 0,len(nums)-1 37 | while l < r: 38 | s = nums[l] + nums[r] 39 | if s == target: 40 | results.append(result + [nums[l], nums[r]]) 41 | l += 1 42 | while l < r and nums[l] == nums[l-1]: 43 | l += 1 44 | elif s < target: 45 | l += 1 46 | else: 47 | r -= 1 48 | else: # recursively reduce N 49 | for i in range(len(nums)-N+1): 50 | if i == 0 or (i > 0 and nums[i-1] != nums[i]): 51 | findNsum(nums[i+1:], target-nums[i], N-1, result+[nums[i]], results) 52 | 53 | results = [] 54 | findNsum(sorted(nums), target, 4, [], results) 55 | return results 56 | -------------------------------------------------------------------------------- /solutions/0019-remove-nth-node-from-end-of-list/remove-nth-node-from-end-of-list.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a linked list, remove the n-th node from the end of list and return its head. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Given linked list: 1->2->3->4->5, and n = 2. 10 | # 11 | # After removing the second node from the end, the linked list becomes 1->2->3->5. 12 | # 13 | # 14 | # Note: 15 | # 16 | # Given n will always be valid. 17 | # 18 | # Follow up: 19 | # 20 | # Could you do this in one pass? 21 | # 22 | 23 | 24 | # Definition for singly-linked list. 25 | # class ListNode(object): 26 | # def __init__(self, x): 27 | # self.val = x 28 | # self.next = None 29 | 30 | class Solution(object): 31 | def removeNthFromEnd(self, head, n): 32 | """ 33 | :type head: ListNode 34 | :type n: int 35 | :rtype: ListNode 36 | """ 37 | dummy = ListNode(0) 38 | dummy.next = head 39 | fast = slow = dummy 40 | 41 | while n: 42 | fast = fast.next 43 | n = n-1 44 | 45 | while fast.next: 46 | fast = fast.next 47 | slow = slow.next 48 | slow.next = slow.next.next 49 | return dummy.next 50 | 51 | -------------------------------------------------------------------------------- /solutions/0020-valid-parentheses/valid-parentheses.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. 5 | # 6 | # An input string is valid if: 7 | # 8 | # 9 | # Open brackets must be closed by the same type of brackets. 10 | # Open brackets must be closed in the correct order. 11 | # 12 | # 13 | # Note that an empty string is also considered valid. 14 | # 15 | # Example 1: 16 | # 17 | # 18 | # Input: "()" 19 | # Output: true 20 | # 21 | # 22 | # Example 2: 23 | # 24 | # 25 | # Input: "()[]{}" 26 | # Output: true 27 | # 28 | # 29 | # Example 3: 30 | # 31 | # 32 | # Input: "(]" 33 | # Output: false 34 | # 35 | # 36 | # Example 4: 37 | # 38 | # 39 | # Input: "([)]" 40 | # Output: false 41 | # 42 | # 43 | # Example 5: 44 | # 45 | # 46 | # Input: "{[]}" 47 | # Output: true 48 | # 49 | # 50 | 51 | 52 | class Solution(object): 53 | def isValid(self, s): 54 | """ 55 | :type s: str 56 | :rtype: bool 57 | """ 58 | pattern = { 59 | '(': ')', 60 | '{': '}', 61 | '[': ']' 62 | } 63 | lst = [] 64 | end = None 65 | for item in s: 66 | if item in list(pattern.keys()): 67 | lst.append(item) 68 | end = item 69 | # elif end == None: # 起手是value 的情况 70 | # return False 71 | elif end and pattern[end] == item: 72 | lst.pop() 73 | end = lst[-1] if lst else None 74 | else: 75 | return False 76 | return len(lst)==0 77 | -------------------------------------------------------------------------------- /solutions/0021-merge-two-sorted-lists/merge-two-sorted-lists.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists. 5 | # 6 | # Example: 7 | # 8 | # Input: 1->2->4, 1->3->4 9 | # Output: 1->1->2->3->4->4 10 | # 11 | # 12 | 13 | 14 | # Definition for singly-linked list. 15 | # class ListNode(object): 16 | # def __init__(self, x): 17 | # self.val = x 18 | # self.next = None 19 | 20 | class Solution(object): 21 | def mergeTwoLists(self, l1, l2): 22 | """ 23 | :type l1: ListNode 24 | :type l2: ListNode 25 | :rtype: ListNode 26 | """ 27 | h = tail = ListNode(0) 28 | while l1 and l2: 29 | if l1.val <= l2.val: 30 | tail.next = l1 31 | l1 = l1.next 32 | else: 33 | tail.next = l2 34 | l2 = l2.next 35 | tail = tail.next 36 | 37 | tail.next = l1 or l2 38 | return h.next 39 | -------------------------------------------------------------------------------- /solutions/0022-generate-parentheses/generate-parentheses.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # 5 | # Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 6 | # 7 | # 8 | # 9 | # For example, given n = 3, a solution set is: 10 | # 11 | # 12 | # [ 13 | # "((()))", 14 | # "(()())", 15 | # "(())()", 16 | # "()(())", 17 | # "()()()" 18 | # ] 19 | # 20 | 21 | 22 | class Solution(object): 23 | def generateParenthesis(self, n): 24 | """ 25 | :type n: int 26 | :rtype: List[str] 27 | """ 28 | lst = [] 29 | def generate(cur, left, right): 30 | 31 | if left > right: 32 | return 33 | if left == 0 and right == 0: 34 | lst.append(cur) 35 | return 36 | if left > 0: 37 | generate(cur + '(', left - 1, right) 38 | if right > 0: 39 | generate(cur + ')', left, right - 1) 40 | generate('', n, n) 41 | return lst 42 | 43 | 44 | -------------------------------------------------------------------------------- /solutions/0023-merge-k-sorted-lists/merge-k-sorted-lists.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: 10 | # [ 11 | #   1->4->5, 12 | #   1->3->4, 13 | #   2->6 14 | # ] 15 | # Output: 1->1->2->3->4->4->5->6 16 | # 17 | # 18 | 19 | 20 | # Definition for singly-linked list. 21 | # class ListNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.next = None 25 | 26 | class Solution(object): 27 | def mergeKLists(self, lists): 28 | 29 | if not lists: 30 | return None 31 | 32 | dummyNode = cur = ListNode(0) 33 | minHeap = [(l.val, l) for l in lists if l] 34 | heapq.heapify(minHeap) 35 | 36 | while minHeap: 37 | cur.next = heapq.heappop(minHeap)[1] 38 | cur = cur.next 39 | 40 | if cur.next: 41 | heapq.heappush(minHeap, (cur.next.val, cur.next)) 42 | 43 | return dummyNode.next 44 | -------------------------------------------------------------------------------- /solutions/0024-swap-nodes-in-pairs/swap-nodes-in-pairs.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a linked list, swap every two adjacent nodes and return its head. 5 | # 6 | # You may not modify the values in the list's nodes, only nodes itself may be changed. 7 | # 8 | #   9 | # 10 | # Example: 11 | # 12 | # 13 | # Given 1->2->3->4, you should return the list as 2->1->4->3. 14 | # 15 | # 16 | 17 | 18 | # Definition for singly-linked list. 19 | # class ListNode(object): 20 | # def __init__(self, x): 21 | # self.val = x 22 | # self.next = None 23 | 24 | class Solution(object): 25 | def swapPairs(self, head): 26 | """ 27 | :type head: ListNode 28 | :rtype: ListNode 29 | """ 30 | dummy = h = ListNode(0) 31 | step = 1 32 | tmp = None 33 | while head: 34 | if step % 2: 35 | tmp = ListNode(head.val) 36 | else: 37 | h.next = ListNode(head.val) 38 | h.next.next = tmp 39 | h = h.next.next 40 | tmp = None 41 | head = head.next 42 | step += 1 43 | if tmp: 44 | h.next = tmp 45 | return dummy.next 46 | -------------------------------------------------------------------------------- /solutions/0025-reverse-nodes-in-k-group/reverse-nodes-in-k-group.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. 5 | # 6 | # k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. 7 | # 8 | # 9 | # 10 | # 11 | # Example: 12 | # 13 | # Given this linked list: 1->2->3->4->5 14 | # 15 | # For k = 2, you should return: 2->1->4->3->5 16 | # 17 | # For k = 3, you should return: 3->2->1->4->5 18 | # 19 | # Note: 20 | # 21 | # 22 | # Only constant extra memory is allowed. 23 | # You may not alter the values in the list's nodes, only nodes itself may be changed. 24 | # 25 | # 26 | 27 | 28 | # Definition for singly-linked list. 29 | # class ListNode(object): 30 | # def __init__(self, x): 31 | # self.val = x 32 | # self.next = None 33 | 34 | class Solution(object): 35 | def reverseKGroup(self, head, k): 36 | """ 37 | :type head: ListNode 38 | :type k: int 39 | :rtype: ListNode 40 | """ 41 | if not head: 42 | return head 43 | 44 | h = head 45 | stack = [] 46 | result = dummy = ListNode(-1) 47 | i = 0 48 | while h: 49 | 50 | stack.append(h.val) 51 | 52 | if len(stack) == k: 53 | tmp_head, tmp_tail = self.putStacktoLinkList(stack) 54 | stack = [] 55 | dummy.next = tmp_head 56 | dummy = tmp_tail 57 | h = h.next 58 | 59 | if stack: 60 | for _,v in enumerate(stack): 61 | l = ListNode(v) 62 | dummy.next = l 63 | dummy = dummy.next 64 | return result.next 65 | 66 | def putStacktoLinkList(self, stack): 67 | head = cur = ListNode(stack.pop()) 68 | while stack: 69 | l = ListNode(stack.pop()) 70 | cur.next = l 71 | cur = cur.next 72 | return head, cur 73 | 74 | -------------------------------------------------------------------------------- /solutions/0026-remove-duplicates-from-sorted-array/remove-duplicates-from-sorted-array.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length. 5 | # 6 | # Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Given nums = [1,1,2], 12 | # 13 | # Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. 14 | # 15 | # It doesn't matter what you leave beyond the returned length. 16 | # 17 | # Example 2: 18 | # 19 | # 20 | # Given nums = [0,0,1,1,1,2,2,3,3,4], 21 | # 22 | # Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively. 23 | # 24 | # It doesn't matter what values are set beyond the returned length. 25 | # 26 | # 27 | # Clarification: 28 | # 29 | # Confused why the returned value is an integer but your answer is an array? 30 | # 31 | # Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well. 32 | # 33 | # Internally you can think of this: 34 | # 35 | # 36 | # // nums is passed in by reference. (i.e., without making a copy) 37 | # int len = removeDuplicates(nums); 38 | # 39 | # // any modification to nums in your function would be known by the caller. 40 | # // using the length returned by your function, it prints the first len elements. 41 | # for (int i = 0; i < len; i++) { 42 | #     print(nums[i]); 43 | # } 44 | # 45 | 46 | 47 | class Solution(object): 48 | def removeDuplicates(self, nums): 49 | """ 50 | :type nums: List[int] 51 | :rtype: int 52 | """ 53 | if not nums: 54 | return 0 55 | n = len(nums) 56 | count = curr = 1 57 | while count < n: 58 | if nums[curr] != nums[curr-1]: 59 | curr += 1 60 | else: 61 | del nums[curr] 62 | count += 1 63 | return curr 64 | -------------------------------------------------------------------------------- /solutions/0027-remove-element/remove-element.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array nums and a value val, remove all instances of that value in-place and return the new length. 5 | # 6 | # Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 7 | # 8 | # The order of elements can be changed. It doesn't matter what you leave beyond the new length. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Given nums = [3,2,2,3], val = 3, 14 | # 15 | # Your function should return length = 2, with the first two elements of nums being 2. 16 | # 17 | # It doesn't matter what you leave beyond the returned length. 18 | # 19 | # 20 | # Example 2: 21 | # 22 | # 23 | # Given nums = [0,1,2,2,3,0,4,2], val = 2, 24 | # 25 | # Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4. 26 | # 27 | # Note that the order of those five elements can be arbitrary. 28 | # 29 | # It doesn't matter what values are set beyond the returned length. 30 | # 31 | # Clarification: 32 | # 33 | # Confused why the returned value is an integer but your answer is an array? 34 | # 35 | # Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well. 36 | # 37 | # Internally you can think of this: 38 | # 39 | # 40 | # // nums is passed in by reference. (i.e., without making a copy) 41 | # int len = removeElement(nums, val); 42 | # 43 | # // any modification to nums in your function would be known by the caller. 44 | # // using the length returned by your function, it prints the first len elements. 45 | # for (int i = 0; i < len; i++) { 46 | #     print(nums[i]); 47 | # } 48 | # 49 | 50 | 51 | class Solution(object): 52 | def removeElement(self, nums, val): 53 | """ 54 | :type nums: List[int] 55 | :type val: int 56 | :rtype: int 57 | """ 58 | i = 0 59 | l = len(nums) 60 | 61 | while i < l: 62 | if nums[i] == val: 63 | del nums[i] 64 | l = l-1 65 | else: 66 | i = i+1 67 | 68 | return len(nums) 69 | -------------------------------------------------------------------------------- /solutions/0028-implement-strstr/implement-strstr.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Implement strStr(). 5 | # 6 | # Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: haystack = "hello", needle = "ll" 12 | # Output: 2 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: haystack = "aaaaa", needle = "bba" 19 | # Output: -1 20 | # 21 | # 22 | # Clarification: 23 | # 24 | # What should we return when needle is an empty string? This is a great question to ask during an interview. 25 | # 26 | # For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf(). 27 | # 28 | 29 | 30 | class Solution(object): 31 | def strStr(self, haystack, needle): 32 | """ 33 | :type haystack: str 34 | :type needle: str 35 | :rtype: int 36 | """ 37 | if not needle: 38 | return 0 39 | lst = haystack.split(needle) 40 | if len(lst) == 1: 41 | return -1 42 | else: 43 | return len(lst[0]) 44 | -------------------------------------------------------------------------------- /solutions/0034-find-first-and-last-position-of-element-in-sorted-array/find-first-and-last-position-of-element-in-sorted-array.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value. 5 | # 6 | # Your algorithm's runtime complexity must be in the order of O(log n). 7 | # 8 | # If the target is not found in the array, return [-1, -1]. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: nums = [5,7,7,8,8,10], target = 8 14 | # Output: [3,4] 15 | # 16 | # Example 2: 17 | # 18 | # 19 | # Input: nums = [5,7,7,8,8,10], target = 6 20 | # Output: [-1,-1] 21 | # 22 | 23 | 24 | class Solution(object): 25 | def searchRange(self, nums, target): 26 | """ 27 | :type nums: List[int] 28 | :type target: int 29 | :rtype: List[int] 30 | """ 31 | n = len(nums) 32 | left, right = -1, -1 33 | l, r = 0, n-1 34 | while l < r: 35 | m = (l+r)/2 36 | if nums[m] < target: l = m+1 37 | else: r = m 38 | if nums[l] != target: return -1, -1 39 | left = l 40 | l, r = left, n-1 41 | while l < r: 42 | m = (l+r)/2+1 43 | if nums[m] == target: l = m 44 | else: r = m-1 45 | right = l 46 | return left, right 47 | -------------------------------------------------------------------------------- /solutions/0035-search-insert-position/search-insert-position.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. 5 | # 6 | # You may assume no duplicates in the array. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: [1,3,5,6], 5 12 | # Output: 2 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: [1,3,5,6], 2 19 | # Output: 1 20 | # 21 | # 22 | # Example 3: 23 | # 24 | # 25 | # Input: [1,3,5,6], 7 26 | # Output: 4 27 | # 28 | # 29 | # Example 4: 30 | # 31 | # 32 | # Input: [1,3,5,6], 0 33 | # Output: 0 34 | # 35 | # 36 | 37 | 38 | class Solution(object): 39 | def searchInsert(self, nums, target): 40 | """ 41 | :type nums: List[int] 42 | :type target: int 43 | :rtype: int 44 | """ 45 | if not nums: 46 | return 0 47 | 48 | for idx,val in enumerate(nums): 49 | if val >= target: 50 | return idx 51 | 52 | return len(nums) 53 | -------------------------------------------------------------------------------- /solutions/0038-count-and-say/count-and-say.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # The count-and-say sequence is the sequence of integers with the first five terms as following: 5 | # 6 | # 7 | # 1. 1 8 | # 2. 11 9 | # 3. 21 10 | # 4. 1211 11 | # 5. 111221 12 | # 13 | # 14 | # 1 is read off as "one 1" or 11. 15 | # 11 is read off as "two 1s" or 21. 16 | # 21 is read off as "one 2, then one 1" or 1211. 17 | # 18 | # Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence. 19 | # 20 | # Note: Each term of the sequence of integers will be represented as a string. 21 | # 22 | #   23 | # 24 | # Example 1: 25 | # 26 | # 27 | # Input: 1 28 | # Output: "1" 29 | # 30 | # 31 | # Example 2: 32 | # 33 | # 34 | # Input: 4 35 | # Output: "1211" 36 | # 37 | 38 | 39 | class Solution(object): 40 | def countAndSay(self, n): 41 | """ 42 | :type n: int 43 | :rtype: str 44 | """ 45 | s = '1' 46 | for i in range(n-1): 47 | count = 1 48 | temp = [] 49 | for index in range(1, len(s)): 50 | if s[index] == s[index-1]: 51 | count += 1 52 | else: 53 | temp.append(str(count)) 54 | temp.append(s[index-1]) 55 | count = 1 56 | temp.append(str(count)) 57 | temp.append(s[-1]) 58 | s = ''.join(temp) 59 | return s 60 | -------------------------------------------------------------------------------- /solutions/0039-combination-sum/combination-sum.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. 5 | # 6 | # The same repeated number may be chosen from candidates unlimited number of times. 7 | # 8 | # Note: 9 | # 10 | # 11 | # All numbers (including target) will be positive integers. 12 | # The solution set must not contain duplicate combinations. 13 | # 14 | # 15 | # Example 1: 16 | # 17 | # 18 | # Input: candidates = [2,3,6,7], target = 7, 19 | # A solution set is: 20 | # [ 21 | # [7], 22 | # [2,2,3] 23 | # ] 24 | # 25 | # 26 | # Example 2: 27 | # 28 | # 29 | # Input: candidates = [2,3,5], target = 8, 30 | # A solution set is: 31 | # [ 32 | #   [2,2,2,2], 33 | #   [2,3,3], 34 | #   [3,5] 35 | # ] 36 | # 37 | # 38 | 39 | 40 | class Solution(object): 41 | def combinationSum(self, candidates, target): 42 | """ 43 | :type candidates: List[int] 44 | :type target: int 45 | :rtype: List[List[int]] 46 | """ 47 | res = [] 48 | candidates.sort() 49 | self.dfs(candidates, target, 0, [], res) 50 | return res 51 | 52 | def dfs(self, nums, target, index, path, res): 53 | if target < 0: 54 | return # backtracking 55 | if target == 0: 56 | res.append(path) 57 | return 58 | for i in xrange(index, len(nums)): 59 | self.dfs(nums, target-nums[i], i, path+[nums[i]], res) 60 | -------------------------------------------------------------------------------- /solutions/0041-first-missing-positive/first-missing-positive.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an unsorted integer array, find the smallest missing positive integer. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: [1,2,0] 10 | # Output: 3 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: [3,4,-1,1] 17 | # Output: 2 18 | # 19 | # 20 | # Example 3: 21 | # 22 | # 23 | # Input: [7,8,9,11,12] 24 | # Output: 1 25 | # 26 | # 27 | # Note: 28 | # 29 | # Your algorithm should run in O(n) time and uses constant extra space. 30 | # 31 | 32 | 33 | class Solution(object): 34 | def firstMissingPositive(self, nums): 35 | """ 36 | :type nums: List[int] 37 | :rtype: int 38 | """ 39 | length = len(nums) 40 | if len(nums) == 0: 41 | return 1 42 | lst = range(1, length+2) 43 | for i in nums: 44 | if i > 0 and i < length+1 and i in lst: 45 | lst.remove(i) 46 | return lst[0] 47 | -------------------------------------------------------------------------------- /solutions/0048-rotate-image/rotate-image.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # You are given an n x n 2D matrix representing an image. 5 | # 6 | # Rotate the image by 90 degrees (clockwise). 7 | # 8 | # Note: 9 | # 10 | # You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation. 11 | # 12 | # Example 1: 13 | # 14 | # 15 | # Given input matrix = 16 | # [ 17 | # [1,2,3], 18 | # [4,5,6], 19 | # [7,8,9] 20 | # ], 21 | # 22 | # rotate the input matrix in-place such that it becomes: 23 | # [ 24 | # [7,4,1], 25 | # [8,5,2], 26 | # [9,6,3] 27 | # ] 28 | # 29 | # 30 | # Example 2: 31 | # 32 | # 33 | # Given input matrix = 34 | # [ 35 | # [ 5, 1, 9,11], 36 | # [ 2, 4, 8,10], 37 | # [13, 3, 6, 7], 38 | # [15,14,12,16] 39 | # ], 40 | # 41 | # rotate the input matrix in-place such that it becomes: 42 | # [ 43 | # [15,13, 2, 5], 44 | # [14, 3, 4, 1], 45 | # [12, 6, 8, 9], 46 | # [16, 7,10,11] 47 | # ] 48 | # 49 | # 50 | 51 | 52 | class Solution(object): 53 | def rotate(self, matrix): 54 | """ 55 | :type matrix: List[List[int]] 56 | :rtype: void Do not return anything, modify matrix in-place instead. 57 | """ 58 | matrix[:] = zip(*matrix[::-1]) 59 | -------------------------------------------------------------------------------- /solutions/0050-powx-n/powx-n.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Implement pow(x, n), which calculates x raised to the power n (xn). 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 2.00000, 10 10 | # Output: 1024.00000 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: 2.10000, 3 17 | # Output: 9.26100 18 | # 19 | # 20 | # Example 3: 21 | # 22 | # 23 | # Input: 2.00000, -2 24 | # Output: 0.25000 25 | # Explanation: 2-2 = 1/22 = 1/4 = 0.25 26 | # 27 | # 28 | # Note: 29 | # 30 | # 31 | # -100.0 < x < 100.0 32 | # n is a 32-bit signed integer, within the range [−231, 231 − 1] 33 | # 34 | # 35 | 36 | 37 | class Solution(object): 38 | def myPow(self, x, n): 39 | """ 40 | :type x: float 41 | :type n: int 42 | :rtype: float 43 | """ 44 | if not n: 45 | return 1 46 | if n < 0: 47 | return 1 / self.myPow(x, -n) 48 | if n % 2: 49 | return x * self.myPow(x, n-1) 50 | return self.myPow(x*x, n/2) 51 | -------------------------------------------------------------------------------- /solutions/0053-maximum-subarray/maximum-subarray.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: [-2,1,-3,4,-1,2,1,-5,4], 10 | # Output: 6 11 | # Explanation: [4,-1,2,1] has the largest sum = 6. 12 | # 13 | # 14 | # Follow up: 15 | # 16 | # If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle. 17 | # 18 | 19 | 20 | class Solution(object): 21 | def maxSubArray(self, nums): 22 | """ 23 | :type nums: List[int] 24 | :rtype: int 25 | """ 26 | if not nums: 27 | return 0 28 | 29 | curSum = maxSum = nums[0] 30 | for num in nums[1:]: 31 | curSum = max(num, curSum + num) 32 | maxSum = max(maxSum, curSum) 33 | 34 | return maxSum 35 | -------------------------------------------------------------------------------- /solutions/0054-spiral-matrix/spiral-matrix.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 10 | # [ 11 | # [ 1, 2, 3 ], 12 | # [ 4, 5, 6 ], 13 | # [ 7, 8, 9 ] 14 | # ] 15 | # Output: [1,2,3,6,9,8,7,4,5] 16 | # 17 | # 18 | # Example 2: 19 | # 20 | # Input: 21 | # [ 22 | # [1, 2, 3, 4], 23 | # [5, 6, 7, 8], 24 | # [9,10,11,12] 25 | # ] 26 | # Output: [1,2,3,4,8,12,11,10,9,5,6,7] 27 | # 28 | 29 | 30 | class Solution(object): 31 | def spiralOrder(self, matrix): 32 | """ 33 | :type matrix: List[List[int]] 34 | :rtype: List[int] 35 | """ 36 | if not matrix: 37 | return [] 38 | 39 | result = [] 40 | while len(matrix)>0: 41 | t = matrix.pop(0) 42 | matrix = self.trans(matrix) 43 | result += t 44 | return result 45 | 46 | 47 | def trans(self, matrix): 48 | return list(zip(*matrix))[::-1] 49 | -------------------------------------------------------------------------------- /solutions/0055-jump-game/jump-game.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array of non-negative integers, you are initially positioned at the first index of the array. 5 | # 6 | # Each element in the array represents your maximum jump length at that position. 7 | # 8 | # Determine if you are able to reach the last index. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [2,3,1,1,4] 14 | # Output: true 15 | # Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. 16 | # 17 | # 18 | # Example 2: 19 | # 20 | # 21 | # Input: [3,2,1,0,4] 22 | # Output: false 23 | # Explanation: You will always arrive at index 3 no matter what. Its maximum 24 | #   jump length is 0, which makes it impossible to reach the last index. 25 | # 26 | # 27 | 28 | 29 | class Solution(object): 30 | def canJump(self, nums): 31 | """ 32 | :type nums: List[int] 33 | :rtype: bool 34 | """ 35 | 36 | m = 0 37 | for i, n in enumerate(nums): 38 | if i > m: 39 | return False 40 | m = max(m, i+n) 41 | return True 42 | -------------------------------------------------------------------------------- /solutions/0056-merge-intervals/merge-intervals.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a collection of intervals, merge all overlapping intervals. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: [[1,3],[2,6],[8,10],[15,18]] 10 | # Output: [[1,6],[8,10],[15,18]] 11 | # Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. 12 | # 13 | # 14 | # Example 2: 15 | # 16 | # 17 | # Input: [[1,4],[4,5]] 18 | # Output: [[1,5]] 19 | # Explanation: Intervals [1,4] and [4,5] are considered overlapping. 20 | # 21 | # NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature. 22 | # 23 | 24 | 25 | # Definition for an interval. 26 | # class Interval(object): 27 | # def __init__(self, s=0, e=0): 28 | # self.start = s 29 | # self.end = e 30 | 31 | class Solution(object): 32 | def merge(self, intervals): 33 | """ 34 | :type intervals: List[Interval] 35 | :rtype: List[Interval] 36 | """ 37 | if not intervals: 38 | return [] 39 | 40 | intervals.sort(key = lambda x: x.start, reverse=True) 41 | stack = [] 42 | tmp = intervals.pop() 43 | while intervals: 44 | x = intervals.pop() 45 | if tmp.end >= x.start: 46 | tmp.end = max(tmp.end, x.end) 47 | else: 48 | stack.append(tmp) 49 | tmp = x 50 | stack.append(tmp) 51 | return stack 52 | 53 | -------------------------------------------------------------------------------- /solutions/0057-insert-interval/insert-interval.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). 5 | # 6 | # You may assume that the intervals were initially sorted according to their start times. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: intervals = [[1,3],[6,9]], newInterval = [2,5] 12 | # Output: [[1,5],[6,9]] 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] 19 | # Output: [[1,2],[3,10],[12,16]] 20 | # Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]. 21 | # 22 | # NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature. 23 | # 24 | 25 | 26 | # Definition for an interval. 27 | # class Interval(object): 28 | # def __init__(self, s=0, e=0): 29 | # self.start = s 30 | # self.end = e 31 | 32 | class Solution(object): 33 | def insert(self, intervals, newInterval): 34 | """ 35 | :type intervals: List[Interval] 36 | :type newInterval: Interval 37 | :rtype: List[Interval] 38 | """ 39 | if not intervals: 40 | return [newInterval] 41 | 42 | if newInterval.end < intervals[0].start: 43 | return [newInterval] + intervals 44 | 45 | 46 | if newInterval.start > intervals[-1].end: 47 | return intervals + [newInterval] 48 | 49 | tmp = list(filter(lambda i: intervals[i].end>=newInterval.start, range(len(intervals)))) 50 | need_merge = list(filter(lambda i: intervals[i].start<=newInterval.end, tmp)) 51 | 52 | if need_merge: 53 | 54 | min_idx = need_merge[0] 55 | max_idx = need_merge[-1] 56 | # need_merge = intervals[min_idx, max_idx+1] 57 | new_item = Interval(min(intervals[min_idx].start, newInterval.start), max(intervals[max_idx].end, newInterval.end)) 58 | return intervals[:min_idx] + [new_item] + intervals[max_idx+1:] 59 | 60 | else: 61 | idx = tmp[0] 62 | return intervals[:idx] + [newInterval] + intervals[idx:] 63 | 64 | -------------------------------------------------------------------------------- /solutions/0058-length-of-last-word/length-of-last-word.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string. 5 | # 6 | # If the last word does not exist, return 0. 7 | # 8 | # Note: A word is defined as a character sequence consists of non-space characters only. 9 | # 10 | # Example: 11 | # 12 | # 13 | # Input: "Hello World" 14 | # Output: 5 15 | # 16 | # 17 | #   18 | # 19 | 20 | 21 | class Solution(object): 22 | def lengthOfLastWord(self, s): 23 | """ 24 | :type s: str 25 | :rtype: int 26 | """ 27 | if not s: 28 | return 0 29 | 30 | tmp = s.strip().split(' ')[-1] 31 | return len(tmp) 32 | -------------------------------------------------------------------------------- /solutions/0066-plus-one/plus-one.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-empty array of digits representing a non-negative integer, plus one to the integer. 5 | # 6 | # The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit. 7 | # 8 | # You may assume the integer does not contain any leading zero, except the number 0 itself. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [1,2,3] 14 | # Output: [1,2,4] 15 | # Explanation: The array represents the integer 123. 16 | # 17 | # 18 | # Example 2: 19 | # 20 | # 21 | # Input: [4,3,2,1] 22 | # Output: [4,3,2,2] 23 | # Explanation: The array represents the integer 4321. 24 | # 25 | 26 | 27 | class Solution(object): 28 | def plusOne(self, digits): 29 | """ 30 | :type digits: List[int] 31 | :rtype: List[int] 32 | """ 33 | c = 1 34 | result = [] 35 | for i in xrange(len(digits)-1, -1 , -1): 36 | t = c + digits[i] 37 | 38 | if t >= 10: 39 | result.append(t % 10) 40 | c = 1 41 | else: 42 | result.append(t) 43 | c = 0 44 | 45 | if c == 1: 46 | result.append(1) 47 | return result[::-1] 48 | -------------------------------------------------------------------------------- /solutions/0067-add-binary/add-binary.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given two binary strings, return their sum (also a binary string). 5 | # 6 | # The input strings are both non-empty and contains only characters 1 or 0. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: a = "11", b = "1" 12 | # Output: "100" 13 | # 14 | # Example 2: 15 | # 16 | # 17 | # Input: a = "1010", b = "1011" 18 | # Output: "10101" 19 | # 20 | 21 | 22 | class Solution(object): 23 | def addBinary(self, a, b): 24 | """ 25 | :type a: str 26 | :type b: str 27 | :rtype: str 28 | """ 29 | num = int(a, 2) + int(b,2) 30 | return bin(num)[2:] 31 | -------------------------------------------------------------------------------- /solutions/0070-climbing-stairs/climbing-stairs.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # You are climbing a stair case. It takes n steps to reach to the top. 5 | # 6 | # Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 7 | # 8 | # Note: Given n will be a positive integer. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: 2 14 | # Output: 2 15 | # Explanation: There are two ways to climb to the top. 16 | # 1. 1 step + 1 step 17 | # 2. 2 steps 18 | # 19 | # 20 | # Example 2: 21 | # 22 | # 23 | # Input: 3 24 | # Output: 3 25 | # Explanation: There are three ways to climb to the top. 26 | # 1. 1 step + 1 step + 1 step 27 | # 2. 1 step + 2 steps 28 | # 3. 2 steps + 1 step 29 | # 30 | # 31 | 32 | 33 | class Solution(object): 34 | def climbStairs(self, n): 35 | """ 36 | :type n: int 37 | :rtype: int 38 | """ 39 | if n == 1: 40 | return 1 41 | a, b = 1, 2 42 | for i in xrange(2, n): 43 | tmp = b 44 | b = a+b 45 | a = tmp 46 | return b 47 | -------------------------------------------------------------------------------- /solutions/0071-simplify-path/simplify-path.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an absolute path for a file (Unix-style), simplify it. Or in other words, convert it to the canonical path. 5 | # 6 | # In a UNIX-style file system, a period . refers to the current directory. Furthermore, a double period .. moves the directory up a level. For more information, see: Absolute path vs relative path in Linux/Unix 7 | # 8 | # Note that the returned canonical path must always begin with a slash /, and there must be only a single slash / between two directory names. The last directory name (if it exists) must not end with a trailing /. Also, the canonical path must be the shortest string representing the absolute path. 9 | # 10 | #   11 | # 12 | # Example 1: 13 | # 14 | # 15 | # Input: "/home/" 16 | # Output: "/home" 17 | # Explanation: Note that there is no trailing slash after the last directory name. 18 | # 19 | # 20 | # Example 2: 21 | # 22 | # 23 | # Input: "/../" 24 | # Output: "/" 25 | # Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go. 26 | # 27 | # 28 | # Example 3: 29 | # 30 | # 31 | # Input: "/home//foo/" 32 | # Output: "/home/foo" 33 | # Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one. 34 | # 35 | # 36 | # Example 4: 37 | # 38 | # 39 | # Input: "/a/./b/../../c/" 40 | # Output: "/c" 41 | # 42 | # 43 | # Example 5: 44 | # 45 | # 46 | # Input: "/a/../../b/../c//.//" 47 | # Output: "/c" 48 | # 49 | # 50 | # Example 6: 51 | # 52 | # 53 | # Input: "/a//b////c/d//././/.." 54 | # Output: "/a/b/c" 55 | # 56 | # 57 | 58 | 59 | class Solution(object): 60 | def simplifyPath(self, path): 61 | """ 62 | :type path: str 63 | :rtype: str 64 | """ 65 | # 思路: 66 | # 1. split / 形成List 67 | # 2. 如果 .. 就 pop 前面的 68 | # 3. 还要考虑 '///' '/...' 69 | places = [p for p in path.split("/") if p!="." and p!=""] 70 | stack = [] 71 | for p in places: 72 | if p == "..": 73 | if len(stack) > 0: 74 | stack.pop() 75 | else: 76 | stack.append(p) 77 | return "/" + "/".join(stack) 78 | -------------------------------------------------------------------------------- /solutions/0073-set-matrix-zeroes/set-matrix-zeroes.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 10 | # [ 11 | #   [1,1,1], 12 | #   [1,0,1], 13 | #   [1,1,1] 14 | # ] 15 | # Output: 16 | # [ 17 | #   [1,0,1], 18 | #   [0,0,0], 19 | #   [1,0,1] 20 | # ] 21 | # 22 | # 23 | # Example 2: 24 | # 25 | # 26 | # Input: 27 | # [ 28 | #   [0,1,2,0], 29 | #   [3,4,5,2], 30 | #   [1,3,1,5] 31 | # ] 32 | # Output: 33 | # [ 34 | #   [0,0,0,0], 35 | #   [0,4,5,0], 36 | #   [0,3,1,0] 37 | # ] 38 | # 39 | # 40 | # Follow up: 41 | # 42 | # 43 | # A straight forward solution using O(mn) space is probably a bad idea. 44 | # A simple improvement uses O(m + n) space, but still not the best solution. 45 | # Could you devise a constant space solution? 46 | # 47 | # 48 | 49 | 50 | class Solution(object): 51 | def setZeroes(self, matrix): 52 | """ 53 | :type matrix: List[List[int]] 54 | :rtype: void Do not return anything, modify matrix in-place instead. 55 | """ 56 | 57 | if not matrix: 58 | return matrix 59 | 60 | # find all (row, col) value 0 and put to stack 61 | stack = [] 62 | rows = len(matrix) 63 | cols = len(matrix[0]) 64 | for row in xrange(rows): 65 | for col in xrange(cols): 66 | if matrix[row][col] == 0: 67 | stack.append((row, col)) 68 | 69 | # calc 0 rows and cols 70 | rows_zero = set([x[0] for x in stack]) 71 | cols_zero = set([x[1] for x in stack]) 72 | 73 | 74 | # set rows zero and cols zero 75 | for i in rows_zero: 76 | matrix[i] = [0] * cols 77 | 78 | for j in cols_zero: 79 | for i in xrange(rows): 80 | matrix[i][j] = 0 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /solutions/0075-sort-colors/sort-colors.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue. 5 | # 6 | # Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively. 7 | # 8 | # Note: You are not suppose to use the library's sort function for this problem. 9 | # 10 | # Example: 11 | # 12 | # 13 | # Input: [2,0,2,1,1,0] 14 | # Output: [0,0,1,1,2,2] 15 | # 16 | # Follow up: 17 | # 18 | # 19 | # A rather straight forward solution is a two-pass algorithm using counting sort. 20 | # First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. 21 | # Could you come up with a one-pass algorithm using only constant space? 22 | # 23 | # 24 | 25 | 26 | class Solution(object): 27 | def sortColors(self, nums): 28 | """ 29 | :type nums: List[int] 30 | :rtype: void Do not return anything, modify nums in-place instead. 31 | """ 32 | nums.sort() 33 | -------------------------------------------------------------------------------- /solutions/0077-combinations/combinations.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: n = 4, k = 2 10 | # Output: 11 | # [ 12 | # [2,4], 13 | # [3,4], 14 | # [2,3], 15 | # [1,2], 16 | # [1,3], 17 | # [1,4], 18 | # ] 19 | # 20 | # 21 | 22 | 23 | class Solution(object): 24 | def combine(self, n, k): 25 | """ 26 | :type n: int 27 | :type k: int 28 | :rtype: List[List[int]] 29 | """ 30 | if k == 1: 31 | return [[i] for i in range(1, n+1)] 32 | if n == k: 33 | return [[i for i in range(1, n+1)]] 34 | return [i + [n] for i in self.combine(n-1,k-1)] + [i for i in self.combine(n-1, k)] 35 | -------------------------------------------------------------------------------- /solutions/0078-subsets/subsets.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a set of distinct integers, nums, return all possible subsets (the power set). 5 | # 6 | # Note: The solution set must not contain duplicate subsets. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: nums = [1,2,3] 12 | # Output: 13 | # [ 14 | # [3], 15 | #   [1], 16 | #   [2], 17 | #   [1,2,3], 18 | #   [1,3], 19 | #   [2,3], 20 | #   [1,2], 21 | #   [] 22 | # ] 23 | # 24 | 25 | 26 | class Solution(object): 27 | def subsets(self, nums): 28 | """ 29 | :type nums: List[int] 30 | :rtype: List[List[int]] 31 | """ 32 | if not nums: 33 | return [[]] 34 | else: 35 | last = nums[-1] 36 | tmp = self.subsets(nums[:-1]) 37 | tmp2 = [i + [last] for i in tmp] 38 | return tmp+tmp2 39 | -------------------------------------------------------------------------------- /solutions/0079-word-search/word-search.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a 2D board and a word, find if the word exists in the grid. 5 | # 6 | # The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once. 7 | # 8 | # Example: 9 | # 10 | # 11 | # board = 12 | # [ 13 | # ['A','B','C','E'], 14 | # ['S','F','C','S'], 15 | # ['A','D','E','E'] 16 | # ] 17 | # 18 | # Given word = "ABCCED", return true. 19 | # Given word = "SEE", return true. 20 | # Given word = "ABCB", return false. 21 | # 22 | # 23 | 24 | 25 | class Solution(object): 26 | def exist(self, board, word): 27 | """ 28 | :type board: List[List[str]] 29 | :type word: str 30 | :rtype: bool 31 | """ 32 | if not board: 33 | return False 34 | for i in xrange(len(board)): 35 | for j in xrange(len(board[0])): 36 | if self.dfs(board, i, j, word): 37 | return True 38 | return False 39 | 40 | # check whether can find word, start at (i,j) position 41 | def dfs(self, board, i, j, word): 42 | if len(word) == 0: # all the characters are checked 43 | return True 44 | if i<0 or i>=len(board) or j<0 or j>=len(board[0]) or word[0]!=board[i][j]: 45 | return False 46 | tmp = board[i][j] # first character is found, check the remaining part 47 | board[i][j] = "#" # avoid visit agian 48 | # check whether can find "word" along one direction 49 | res = self.dfs(board, i+1, j, word[1:]) or self.dfs(board, i-1, j, word[1:]) \ 50 | or self.dfs(board, i, j+1, word[1:]) or self.dfs(board, i, j-1, word[1:]) 51 | board[i][j] = tmp 52 | return res 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /solutions/0080-remove-duplicates-from-sorted-array-ii/remove-duplicates-from-sorted-array-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length. 5 | # 6 | # Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Given nums = [1,1,1,2,2,3], 12 | # 13 | # Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively. 14 | # 15 | # It doesn't matter what you leave beyond the returned length. 16 | # 17 | # Example 2: 18 | # 19 | # 20 | # Given nums = [0,0,1,1,1,1,2,3,3], 21 | # 22 | # Your function should return length = 7, with the first seven elements of nums being modified to 0, 0, 1, 1, 2, 3 and 3 respectively. 23 | # 24 | # It doesn't matter what values are set beyond the returned length. 25 | # 26 | # 27 | # Clarification: 28 | # 29 | # Confused why the returned value is an integer but your answer is an array? 30 | # 31 | # Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well. 32 | # 33 | # Internally you can think of this: 34 | # 35 | # 36 | # // nums is passed in by reference. (i.e., without making a copy) 37 | # int len = removeDuplicates(nums); 38 | # 39 | # // any modification to nums in your function would be known by the caller. 40 | # // using the length returned by your function, it prints the first len elements. 41 | # for (int i = 0; i < len; i++) { 42 | #     print(nums[i]); 43 | # } 44 | # 45 | # 46 | 47 | 48 | class Solution(object): 49 | def removeDuplicates(self, nums): 50 | """ 51 | :type nums: List[int] 52 | :rtype: int 53 | """ 54 | # recode val counts to a dict 55 | i = 0 56 | for n in nums: 57 | if i < 2 or n > nums[i-2]: 58 | nums[i] = n 59 | i += 1 60 | return i 61 | 62 | -------------------------------------------------------------------------------- /solutions/0083-remove-duplicates-from-sorted-list/remove-duplicates-from-sorted-list.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a sorted linked list, delete all duplicates such that each element appear only once. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: 1->1->2 10 | # Output: 1->2 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: 1->1->2->3->3 17 | # Output: 1->2->3 18 | # 19 | # 20 | 21 | 22 | # Definition for singly-linked list. 23 | # class ListNode(object): 24 | # def __init__(self, x): 25 | # self.val = x 26 | # self.next = None 27 | 28 | class Solution(object): 29 | def deleteDuplicates(self, head): 30 | """ 31 | :type head: ListNode 32 | :rtype: ListNode 33 | """ 34 | t_point = head 35 | while t_point: 36 | while t_point.next and t_point.next.val == t_point.val: 37 | t_point.next = t_point.next.next 38 | t_point = t_point.next 39 | return head 40 | 41 | -------------------------------------------------------------------------------- /solutions/0086-partition-list/partition-list.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. 5 | # 6 | # You should preserve the original relative order of the nodes in each of the two partitions. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: head = 1->4->3->2->5->2, x = 3 12 | # Output: 1->2->2->4->3->5 13 | # 14 | # 15 | 16 | 17 | # Definition for singly-linked list. 18 | # class ListNode(object): 19 | # def __init__(self, x): 20 | # self.val = x 21 | # self.next = None 22 | 23 | class Solution(object): 24 | def partition(self, head, x): 25 | """ 26 | :type head: ListNode 27 | :type x: int 28 | :rtype: ListNode 29 | """ 30 | h1 = t1 = ListNode(-1) 31 | h2 = t2 = ListNode(-1) 32 | dummy = head 33 | while dummy: 34 | if dummy.val < x: 35 | t1.next = dummy 36 | t1 = t1.next 37 | else: 38 | t2.next = dummy 39 | t2 = t2.next 40 | dummy = dummy.next 41 | t2.next = None 42 | t1.next = h2.next 43 | return h1.next 44 | 45 | 46 | -------------------------------------------------------------------------------- /solutions/0088-merge-sorted-array/merge-sorted-array.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 5 | # 6 | # Note: 7 | # 8 | # 9 | # The number of elements initialized in nums1 and nums2 are m and n respectively. 10 | # You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. 11 | # 12 | # 13 | # Example: 14 | # 15 | # 16 | # Input: 17 | # nums1 = [1,2,3,0,0,0], m = 3 18 | # nums2 = [2,5,6], n = 3 19 | # 20 | # Output: [1,2,2,3,5,6] 21 | # 22 | # 23 | 24 | 25 | class Solution(object): 26 | def merge(self, nums1, m, nums2, n): 27 | """ 28 | :type nums1: List[int] 29 | :type m: int 30 | :type nums2: List[int] 31 | :type n: int 32 | :rtype: void Do not return anything, modify nums1 in-place instead. 33 | """ 34 | while m and n: 35 | if nums1[m-1]>=nums2[n-1]: 36 | nums1[m+n-1] = nums1[m-1] 37 | m -= 1 38 | else: 39 | nums1[m+n-1]=nums2[n-1] 40 | n -= 1 41 | 42 | if n>0: 43 | for i in xrange(n): 44 | nums1[i] = nums2[i] 45 | 46 | -------------------------------------------------------------------------------- /solutions/0093-restore-ip-addresses/restore-ip-addresses.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string containing only digits, restore it by returning all possible valid IP address combinations. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: "25525511135" 10 | # Output: ["255.255.11.135", "255.255.111.35"] 11 | # 12 | # 13 | 14 | 15 | class Solution(object): 16 | def restoreIpAddresses(self, s): 17 | """ 18 | :type s: str 19 | :rtype: List[str] 20 | """ 21 | ans = [] 22 | self.helper(ans, s, 4, []) 23 | return ['.'.join(x) for x in ans] 24 | 25 | def helper(self, ans, s, k, temp): 26 | if len(s) > k*3: 27 | return 28 | if k == 0: 29 | ans.append(temp[:]) 30 | else: 31 | for i in range(min(3,len(s)-k+1)): 32 | if i==2 and int(s[:3]) > 255 or i > 0 and s[0] == '0': 33 | continue 34 | self.helper(ans, s[i+1:], k-1, temp+[s[:i+1]]) 35 | -------------------------------------------------------------------------------- /solutions/0094-binary-tree-inorder-traversal/binary-tree-inorder-traversal.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree, return the inorder traversal of its nodes' values. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: [1,null,2,3] 10 | # 1 11 | # \ 12 | # 2 13 | # / 14 | # 3 15 | # 16 | # Output: [1,3,2] 17 | # 18 | # Follow up: Recursive solution is trivial, could you do it iteratively? 19 | # 20 | 21 | 22 | # Definition for a binary tree node. 23 | # class TreeNode(object): 24 | # def __init__(self, x): 25 | # self.val = x 26 | # self.left = None 27 | # self.right = None 28 | 29 | class Solution(object): 30 | def inorderTraversal(self, root): 31 | res = [] 32 | self.helper(root, res) 33 | return res 34 | 35 | def helper(self, root, res): 36 | if root: 37 | self.helper(root.left, res) 38 | res.append(root.val) 39 | self.helper(root.right, res) 40 | 41 | 42 | -------------------------------------------------------------------------------- /solutions/0097-interleaving-string/interleaving-string.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" 10 | # Output: true 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc" 17 | # Output: false 18 | # 19 | # 20 | 21 | 22 | class Solution(object): 23 | def isInterleave(self, s1, s2, s3): 24 | """ 25 | :type s1: str 26 | :type s2: str 27 | :type s3: str 28 | :rtype: bool 29 | """ 30 | 31 | r, c, l= len(s1), len(s2), len(s3) 32 | if r+c != l: 33 | return False 34 | stack, visited = [(0, 0)], set((0, 0)) 35 | while stack: 36 | x, y = stack.pop() 37 | if x+y == l: 38 | return True 39 | if x+1 <= r and s1[x] == s3[x+y] and (x+1, y) not in visited: 40 | stack.append((x+1, y)); visited.add((x+1, y)) 41 | if y+1 <= c and s2[y] == s3[x+y] and (x, y+1) not in visited: 42 | stack.append((x, y+1)); visited.add((x, y+1)) 43 | return False 44 | -------------------------------------------------------------------------------- /solutions/0100-same-tree/same-tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given two binary trees, write a function to check if they are the same or not. 5 | # 6 | # Two binary trees are considered the same if they are structurally identical and the nodes have the same value. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: 1 1 12 | # / \ / \ 13 | # 2 3 2 3 14 | # 15 | # [1,2,3], [1,2,3] 16 | # 17 | # Output: true 18 | # 19 | # 20 | # Example 2: 21 | # 22 | # 23 | # Input: 1 1 24 | # / \ 25 | # 2 2 26 | # 27 | # [1,2], [1,null,2] 28 | # 29 | # Output: false 30 | # 31 | # 32 | # Example 3: 33 | # 34 | # 35 | # Input: 1 1 36 | # / \ / \ 37 | # 2 1 1 2 38 | # 39 | # [1,2,1], [1,1,2] 40 | # 41 | # Output: false 42 | # 43 | # 44 | 45 | 46 | # Definition for a binary tree node. 47 | # class TreeNode(object): 48 | # def __init__(self, x): 49 | # self.val = x 50 | # self.left = None 51 | # self.right = None 52 | 53 | class Solution(object): 54 | def isSameTree(self, p, q): 55 | """ 56 | :type p: TreeNode 57 | :type q: TreeNode 58 | :rtype: bool 59 | """ 60 | stack = [(p, q)] 61 | while stack: 62 | node1, node2 = stack.pop() 63 | if not node1 and not node2: 64 | continue 65 | if None in (node1, node2) or node1.val != node2.val: 66 | return False 67 | if node1.val == node2.val: 68 | stack.append((node1.left, node2.left)) 69 | stack.append((node1.right, node2.right)) 70 | 71 | return True 72 | -------------------------------------------------------------------------------- /solutions/0101-symmetric-tree/symmetric-tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center). 5 | # 6 | # For example, this binary tree [1,2,2,3,4,4,3] is symmetric: 7 | # 8 | # 9 | # 1 10 | # / \ 11 | # 2 2 12 | # / \ / \ 13 | # 3 4 4 3 14 | # 15 | # 16 | #   17 | # 18 | # But the following [1,2,2,null,3,null,3] is not: 19 | # 20 | # 21 | # 1 22 | # / \ 23 | # 2 2 24 | # \ \ 25 | # 3 3 26 | # 27 | # 28 | #   29 | # 30 | # Note: 31 | # Bonus points if you could solve it both recursively and iteratively. 32 | # 33 | 34 | 35 | # Definition for a binary tree node. 36 | # class TreeNode(object): 37 | # def __init__(self, x): 38 | # self.val = x 39 | # self.left = None 40 | # self.right = None 41 | 42 | class Solution(object): 43 | def isSymmetric(self, root): 44 | """ 45 | :type root: TreeNode 46 | :rtype: bool 47 | """ 48 | return self.helper(root,root) 49 | 50 | def helper(self,root1,root2): 51 | if not root1 and not root2: 52 | return True 53 | if not root1 or not root2: 54 | return False 55 | if root1.val != root2.val: 56 | return False 57 | return self.helper(root1.left,root2.right) and self.helper(root1.right,root2.left) 58 | return res 59 | -------------------------------------------------------------------------------- /solutions/0104-maximum-depth-of-binary-tree/maximum-depth-of-binary-tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree, find its maximum depth. 5 | # 6 | # The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 7 | # 8 | # Note: A leaf is a node with no children. 9 | # 10 | # Example: 11 | # 12 | # Given binary tree [3,9,20,null,null,15,7], 13 | # 14 | # 15 | # 3 16 | # / \ 17 | # 9 20 18 | # / \ 19 | # 15 7 20 | # 21 | # return its depth = 3. 22 | # 23 | 24 | 25 | # Definition for a binary tree node. 26 | # class TreeNode(object): 27 | # def __init__(self, x): 28 | # self.val = x 29 | # self.left = None 30 | # self.right = None 31 | 32 | class Solution(object): 33 | def maxDepth(self, root): 34 | """ 35 | :type root: TreeNode 36 | :rtype: int 37 | """ 38 | if not root: 39 | return 0 40 | # if root.left == None and root.right == None: 41 | # return 1 42 | else: 43 | return max(self.maxDepth(root.left), self.maxDepth(root.right))+1 44 | -------------------------------------------------------------------------------- /solutions/0107-binary-tree-level-order-traversal-ii/binary-tree-level-order-traversal-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root). 5 | # 6 | # 7 | # For example: 8 | # Given binary tree [3,9,20,null,null,15,7], 9 | # 10 | # 3 11 | # / \ 12 | # 9 20 13 | # / \ 14 | # 15 7 15 | # 16 | # 17 | # 18 | # return its bottom-up level order traversal as: 19 | # 20 | # [ 21 | # [15,7], 22 | # [9,20], 23 | # [3] 24 | # ] 25 | # 26 | # 27 | 28 | 29 | # Definition for a binary tree node. 30 | # class TreeNode(object): 31 | # def __init__(self, x): 32 | # self.val = x 33 | # self.left = None 34 | # self.right = None 35 | 36 | class Solution(object): 37 | rlst = [] 38 | 39 | def levelOrderBottom(self, root): 40 | """ 41 | :type root: TreeNode 42 | :rtype: List[List[int]] 43 | """ 44 | if not root: 45 | return [] 46 | self.rlst=[] 47 | self.levelList(root, 0) 48 | mx = max([item['hight'] for item in self.rlst]) 49 | rst = [list() for _ in range(mx+1)] 50 | for item in self.rlst: 51 | rst[mx - item['hight']].append(item['val']) 52 | 53 | return rst 54 | 55 | def levelList(self, root, hight): 56 | if root: 57 | self.rlst.append({'val': root.val, 'hight': hight}) 58 | hight = hight + 1 59 | if root.left: 60 | self.levelList(root.left, hight) 61 | if root.right: 62 | self.levelList(root.right, hight) 63 | 64 | -------------------------------------------------------------------------------- /solutions/0108-convert-sorted-array-to-binary-search-tree/convert-sorted-array-to-binary-search-tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 5 | # 6 | # For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Given the sorted array: [-10,-3,0,5,9], 12 | # 13 | # One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 14 | # 15 | # 0 16 | # / \ 17 | # -3 9 18 | # / / 19 | # -10 5 20 | # 21 | # 22 | 23 | 24 | # Definition for a binary tree node. 25 | # class TreeNode(object): 26 | # def __init__(self, x): 27 | # self.val = x 28 | # self.left = None 29 | # self.right = None 30 | 31 | class Solution(object): 32 | def sortedArrayToBST(self, nums): 33 | """ 34 | :type nums: List[int] 35 | :rtype: TreeNode 36 | """ 37 | if not nums: 38 | return None 39 | 40 | mid = len(nums) // 2 41 | 42 | root = TreeNode(nums[mid]) 43 | root.left = self.sortedArrayToBST(nums[:mid]) 44 | root.right = self.sortedArrayToBST(nums[mid+1:]) 45 | 46 | return root 47 | -------------------------------------------------------------------------------- /solutions/0111-minimum-depth-of-binary-tree/minimum-depth-of-binary-tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree, find its minimum depth. 5 | # 6 | # The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 7 | # 8 | # Note: A leaf is a node with no children. 9 | # 10 | # Example: 11 | # 12 | # Given binary tree [3,9,20,null,null,15,7], 13 | # 14 | # 15 | # 3 16 | # / \ 17 | # 9 20 18 | # / \ 19 | # 15 7 20 | # 21 | # return its minimum depth = 2. 22 | # 23 | 24 | 25 | # Definition for a binary tree node. 26 | # class TreeNode(object): 27 | # def __init__(self, x): 28 | # self.val = x 29 | # self.left = None 30 | # self.right = None 31 | 32 | class Solution(object): 33 | def minDepth(self, root): 34 | """ 35 | :type root: TreeNode 36 | :rtype: int 37 | """ 38 | if root == None: 39 | return 0 40 | if root.left==None or root.right==None: 41 | return self.minDepth(root.left)+self.minDepth(root.right)+1 42 | return min(self.minDepth(root.right),self.minDepth(root.left))+1 43 | -------------------------------------------------------------------------------- /solutions/0112-path-sum/path-sum.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 5 | # 6 | # Note: A leaf is a node with no children. 7 | # 8 | # Example: 9 | # 10 | # Given the below binary tree and sum = 22, 11 | # 12 | # 13 | # 5 14 | # / \ 15 | # 4 8 16 | # / / \ 17 | # 11 13 4 18 | # / \ \ 19 | # 7 2 1 20 | # 21 | # 22 | # return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22. 23 | # 24 | 25 | 26 | # Definition for a binary tree node. 27 | # class TreeNode(object): 28 | # def __init__(self, x): 29 | # self.val = x 30 | # self.left = None 31 | # self.right = None 32 | 33 | class Solution(object): 34 | def hasPathSum(self, root, sum): 35 | """ 36 | :type root: TreeNode 37 | :type sum: int 38 | :rtype: bool 39 | """ 40 | if not root: 41 | return False 42 | 43 | stack = [(root, sum)] 44 | while stack: 45 | node, sum = stack.pop() 46 | if not node.left and not node.right and node.val == sum: 47 | return True 48 | 49 | if node.left: 50 | stack.append((node.left, sum-node.val)) 51 | if node.right: 52 | stack.append((node.right, sum-node.val)) 53 | 54 | return False 55 | -------------------------------------------------------------------------------- /solutions/0113-path-sum-ii/path-sum-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum. 5 | # 6 | # Note: A leaf is a node with no children. 7 | # 8 | # Example: 9 | # 10 | # Given the below binary tree and sum = 22, 11 | # 12 | # 13 | # 5 14 | # / \ 15 | # 4 8 16 | # / / \ 17 | # 11 13 4 18 | # / \ / \ 19 | # 7 2 5 1 20 | # 21 | # 22 | # Return: 23 | # 24 | # 25 | # [ 26 | # [5,4,11,2], 27 | # [5,8,4,5] 28 | # ] 29 | # 30 | # 31 | 32 | 33 | # Definition for a binary tree node. 34 | # class TreeNode(object): 35 | # def __init__(self, x): 36 | # self.val = x 37 | # self.left = None 38 | # self.right = None 39 | 40 | class Solution(object): 41 | def pathSum(self, root, sum): 42 | """ 43 | :type root: TreeNode 44 | :type sum: int 45 | :rtype: List[List[int]] 46 | """ 47 | if not root: 48 | return [] 49 | 50 | if not root.left and not root.right and root.val == sum: 51 | return [[root.val]] 52 | 53 | r_left = [] 54 | r_right = [] 55 | 56 | if root.left: 57 | r_left = [[root.val] + l for l in self.pathSum(root.left, sum-root.val)] 58 | 59 | if root.right: 60 | r_right = [[root.val] + l for l in self.pathSum(root.right, sum-root.val)] 61 | 62 | return r_left + r_right 63 | 64 | -------------------------------------------------------------------------------- /solutions/0118-pascals-triangle/pascals-triangle.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-negative integer numRows, generate the first numRows of Pascal's triangle. 5 | # 6 | # 7 | # In Pascal's triangle, each number is the sum of the two numbers directly above it. 8 | # 9 | # Example: 10 | # 11 | # 12 | # Input: 5 13 | # Output: 14 | # [ 15 | # [1], 16 | # [1,1], 17 | # [1,2,1], 18 | # [1,3,3,1], 19 | # [1,4,6,4,1] 20 | # ] 21 | # 22 | # 23 | 24 | 25 | class Solution(object): 26 | def generate(self, numRows): 27 | """ 28 | :type numRows: int 29 | :rtype: List[List[int]] 30 | """ 31 | if numRows == 0: 32 | return [] 33 | 34 | if numRows == 1: 35 | return [[1]] 36 | 37 | tmp = self.generate(numRows-1) 38 | # x = [0] + tmp[-1] 39 | # y = tmp[-1] + [0] 40 | # a = [x[i]+y[i] for i,_ in enumerate(x)] 41 | a = list(map(lambda x, y: x+y, tmp[-1] + [0], [0] + tmp[-1])) 42 | return tmp + [a] 43 | -------------------------------------------------------------------------------- /solutions/0119-pascals-triangle-ii/pascals-triangle-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle. 5 | # 6 | # Note that the row index starts from 0. 7 | # 8 | # 9 | # In Pascal's triangle, each number is the sum of the two numbers directly above it. 10 | # 11 | # Example: 12 | # 13 | # 14 | # Input: 3 15 | # Output: [1,3,3,1] 16 | # 17 | # 18 | # Follow up: 19 | # 20 | # Could you optimize your algorithm to use only O(k) extra space? 21 | # 22 | 23 | 24 | class Solution(object): 25 | def getRow(self, rowIndex): 26 | """ 27 | :type rowIndex: int 28 | :rtype: List[int] 29 | """ 30 | if rowIndex == 0: 31 | return [1] 32 | 33 | tmp = self.getRow(rowIndex-1) 34 | return list(map(lambda a,b:a+b, [0]+tmp, tmp+[0])) 35 | -------------------------------------------------------------------------------- /solutions/0121-best-time-to-buy-and-sell-stock/best-time-to-buy-and-sell-stock.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Say you have an array for which the ith element is the price of a given stock on day i. 5 | # 6 | # If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. 7 | # 8 | # Note that you cannot sell a stock before you buy one. 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [7,1,5,3,6,4] 14 | # Output: 5 15 | # Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. 16 | #   Not 7-1 = 6, as selling price needs to be larger than buying price. 17 | # 18 | # 19 | # Example 2: 20 | # 21 | # 22 | # Input: [7,6,4,3,1] 23 | # Output: 0 24 | # Explanation: In this case, no transaction is done, i.e. max profit = 0. 25 | # 26 | # 27 | 28 | 29 | class Solution(object): 30 | def maxProfit(self, prices): 31 | """ 32 | :type prices: List[int] 33 | :rtype: int 34 | """ 35 | if not prices: 36 | return 0 37 | 38 | profit = 0 39 | cur = prices[0] 40 | for item in prices[1:]: 41 | result = item - cur 42 | if result <= 0: 43 | cur = item 44 | else: 45 | if result > profit: 46 | profit = result 47 | 48 | return profit 49 | 50 | -------------------------------------------------------------------------------- /solutions/0122-best-time-to-buy-and-sell-stock-ii/best-time-to-buy-and-sell-stock-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Say you have an array for which the ith element is the price of a given stock on day i. 5 | # 6 | # Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times). 7 | # 8 | # Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again). 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [7,1,5,3,6,4] 14 | # Output: 7 15 | # Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4. 16 | #   Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3. 17 | # 18 | # 19 | # Example 2: 20 | # 21 | # 22 | # Input: [1,2,3,4,5] 23 | # Output: 4 24 | # Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4. 25 | #   Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are 26 | #   engaging multiple transactions at the same time. You must sell before buying again. 27 | # 28 | # 29 | # Example 3: 30 | # 31 | # 32 | # Input: [7,6,4,3,1] 33 | # Output: 0 34 | # Explanation: In this case, no transaction is done, i.e. max profit = 0. 35 | # 36 | 37 | 38 | class Solution(object): 39 | def maxProfit(self, prices): 40 | """ 41 | :type prices: List[int] 42 | :rtype: int 43 | """ 44 | profit = 0 45 | tmp_profit = 0 46 | if not prices: 47 | return profit 48 | cur = prices[0] 49 | for item in prices[1:]: 50 | if item >= cur: 51 | tmp_profit = tmp_profit+item-cur 52 | else: 53 | profit += tmp_profit 54 | tmp_profit = 0 55 | cur = item 56 | profit += tmp_profit 57 | return profit 58 | -------------------------------------------------------------------------------- /solutions/0125-valid-palindrome/valid-palindrome.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 5 | # 6 | # Note: For the purpose of this problem, we define empty string as valid palindrome. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: "A man, a plan, a canal: Panama" 12 | # Output: true 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: "race a car" 19 | # Output: false 20 | # 21 | # 22 | 23 | 24 | class Solution(object): 25 | def isPalindrome(self, s): 26 | """ 27 | :type s: str 28 | :rtype: bool 29 | """ 30 | s = "".join([c.lower() for c in s if c.isalnum()]) 31 | 32 | return s == s[::-1] 33 | 34 | -------------------------------------------------------------------------------- /solutions/0134-gas-station/gas-station.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. 5 | # 6 | # You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. 7 | # 8 | # Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1. 9 | # 10 | # Note: 11 | # 12 | # 13 | # If there exists a solution, it is guaranteed to be unique. 14 | # Both input arrays are non-empty and have the same length. 15 | # Each element in the input arrays is a non-negative integer. 16 | # 17 | # 18 | # Example 1: 19 | # 20 | # 21 | # Input: 22 | # gas = [1,2,3,4,5] 23 | # cost = [3,4,5,1,2] 24 | # 25 | # Output: 3 26 | # 27 | # Explanation: 28 | # Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4 29 | # Travel to station 4. Your tank = 4 - 1 + 5 = 8 30 | # Travel to station 0. Your tank = 8 - 2 + 1 = 7 31 | # Travel to station 1. Your tank = 7 - 3 + 2 = 6 32 | # Travel to station 2. Your tank = 6 - 4 + 3 = 5 33 | # Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3. 34 | # Therefore, return 3 as the starting index. 35 | # 36 | # 37 | # Example 2: 38 | # 39 | # 40 | # Input: 41 | # gas = [2,3,4] 42 | # cost = [3,4,3] 43 | # 44 | # Output: -1 45 | # 46 | # Explanation: 47 | # You can't start at station 0 or 1, as there is not enough gas to travel to the next station. 48 | # Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4 49 | # Travel to station 0. Your tank = 4 - 3 + 2 = 3 50 | # Travel to station 1. Your tank = 3 - 3 + 3 = 3 51 | # You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3. 52 | # Therefore, you can't travel around the circuit once no matter where you start. 53 | # 54 | # 55 | 56 | 57 | class Solution(object): 58 | def canCompleteCircuit(self, gas, cost): 59 | """ 60 | :type gas: List[int] 61 | :type cost: List[int] 62 | :rtype: int 63 | """ 64 | if len(gas) == 0 or len(cost) == 0 or sum(gas) < sum(cost): 65 | return -1 66 | position = 0 67 | balance = 0 # current tank balance 68 | for i in range(len(gas)): 69 | balance += gas[i] - cost[i] # update balance 70 | if balance < 0: # balance drops to negative, reset the start position 71 | balance = 0 72 | position = i+1 73 | return position 74 | -------------------------------------------------------------------------------- /solutions/0136-single-number/single-number.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-empty array of integers, every element appears twice except for one. Find that single one. 5 | # 6 | # Note: 7 | # 8 | # Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [2,2,1] 14 | # Output: 1 15 | # 16 | # 17 | # Example 2: 18 | # 19 | # 20 | # Input: [4,1,2,1,2] 21 | # Output: 4 22 | # 23 | # 24 | 25 | 26 | class Solution(object): 27 | def singleNumber(self, nums): 28 | """ 29 | :type nums: List[int] 30 | :rtype: int 31 | """ 32 | return reduce(lambda x, y: x ^ y, nums) 33 | -------------------------------------------------------------------------------- /solutions/0137-single-number-ii/single-number-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one. 5 | # 6 | # Note: 7 | # 8 | # Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 9 | # 10 | # Example 1: 11 | # 12 | # 13 | # Input: [2,2,3,2] 14 | # Output: 3 15 | # 16 | # 17 | # Example 2: 18 | # 19 | # 20 | # Input: [0,1,0,1,0,1,99] 21 | # Output: 99 22 | # 23 | 24 | 25 | class Solution(object): 26 | def singleNumber(self, nums): 27 | """ 28 | :type nums: List[int] 29 | :rtype: int 30 | """ 31 | if len(nums) == 1: 32 | return nums[0] 33 | s = sum(set(nums))*3 34 | for n in nums: 35 | s = s - n 36 | return s/2 37 | -------------------------------------------------------------------------------- /solutions/0141-linked-list-cycle/linked-list-cycle.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a linked list, determine if it has a cycle in it. 5 | # 6 | # To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list. 7 | # 8 | #   9 | # 10 | # 11 | # Example 1: 12 | # 13 | # 14 | # Input: head = [3,2,0,-4], pos = 1 15 | # Output: true 16 | # Explanation: There is a cycle in the linked list, where tail connects to the second node. 17 | # 18 | # 19 | # 20 | # 21 | # 22 | # 23 | # Example 2: 24 | # 25 | # 26 | # Input: head = [1,2], pos = 0 27 | # Output: true 28 | # Explanation: There is a cycle in the linked list, where tail connects to the first node. 29 | # 30 | # 31 | # 32 | # 33 | # 34 | # 35 | # Example 3: 36 | # 37 | # 38 | # Input: head = [1], pos = -1 39 | # Output: false 40 | # Explanation: There is no cycle in the linked list. 41 | # 42 | # 43 | # 44 | # 45 | # 46 | #   47 | # 48 | # Follow up: 49 | # 50 | # Can you solve it using O(1) (i.e. constant) memory? 51 | # 52 | 53 | 54 | # Definition for singly-linked list. 55 | # class ListNode(object): 56 | # def __init__(self, x): 57 | # self.val = x 58 | # self.next = None 59 | 60 | class Solution(object): 61 | def hasCycle(self, head): 62 | """ 63 | :type head: ListNode 64 | :rtype: bool 65 | """ 66 | if head is None: 67 | return False 68 | cur = head 69 | dct = {} 70 | while cur.next: 71 | if id(cur) in dct: 72 | return True 73 | dct[id(cur)] = cur 74 | cur = cur.next 75 | 76 | return False 77 | 78 | -------------------------------------------------------------------------------- /solutions/0189-rotate-array/rotate-array.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array, rotate the array to the right by k steps, where k is non-negative. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: [1,2,3,4,5,6,7] and k = 3 10 | # Output: [5,6,7,1,2,3,4] 11 | # Explanation: 12 | # rotate 1 steps to the right: [7,1,2,3,4,5,6] 13 | # rotate 2 steps to the right: [6,7,1,2,3,4,5] 14 | # rotate 3 steps to the right: [5,6,7,1,2,3,4] 15 | # 16 | # 17 | # Example 2: 18 | # 19 | # 20 | # Input: [-1,-100,3,99] and k = 2 21 | # Output: [3,99,-1,-100] 22 | # Explanation: 23 | # rotate 1 steps to the right: [99,-1,-100,3] 24 | # rotate 2 steps to the right: [3,99,-1,-100] 25 | # 26 | # 27 | # Note: 28 | # 29 | # 30 | # Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. 31 | # Could you do it in-place with O(1) extra space? 32 | # 33 | 34 | 35 | class Solution(object): 36 | def rotate(self, nums, k): 37 | """ 38 | :type nums: List[int] 39 | :type k: int 40 | :rtype: void Do not return anything, modify nums in-place instead. 41 | """ 42 | while k>0: 43 | t = nums.pop() 44 | nums.insert(0, t) 45 | k -= 1 46 | -------------------------------------------------------------------------------- /solutions/0206-reverse-linked-list/reverse-linked-list.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Reverse a singly linked list. 5 | # 6 | # Example: 7 | # 8 | # 9 | # Input: 1->2->3->4->5->NULL 10 | # Output: 5->4->3->2->1->NULL 11 | # 12 | # 13 | # Follow up: 14 | # 15 | # A linked list can be reversed either iteratively or recursively. Could you implement both? 16 | # 17 | 18 | 19 | # Definition for singly-linked list. 20 | # class ListNode(object): 21 | # def __init__(self, x): 22 | # self.val = x 23 | # self.next = None 24 | 25 | class Solution(object): 26 | def reverseList(self, head): 27 | """ 28 | :type head: ListNode 29 | :rtype: ListNode 30 | """ 31 | h = head 32 | lst = [] 33 | result = tail = ListNode(None) 34 | while h: 35 | lst.append(h.val) 36 | h=h.next 37 | while lst: 38 | node = ListNode(lst.pop()) 39 | tail.next = node 40 | tail = tail.next 41 | return result.next 42 | -------------------------------------------------------------------------------- /solutions/0227-basic-calculator-ii/basic-calculator-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Implement a basic calculator to evaluate a simple expression string. 5 | # 6 | # The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: "3+2*2" 12 | # Output: 7 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: " 3/2 " 19 | # Output: 1 20 | # 21 | # Example 3: 22 | # 23 | # 24 | # Input: " 3+5 / 2 " 25 | # Output: 5 26 | # 27 | # 28 | # Note: 29 | # 30 | # 31 | # You may assume that the given expression is always valid. 32 | # Do not use the eval built-in library function. 33 | # 34 | # 35 | 36 | 37 | class Solution(object): 38 | def calculate(self, s): 39 | """ 40 | :type s: str 41 | :rtype: int 42 | """ 43 | if not s: 44 | return 0 45 | stack, num ,sign= [], 0, '+' 46 | for i in xrange(len(s)): 47 | if s[i].isdigit(): 48 | num = num*10+ord(s[i])-ord('0') 49 | if (not s[i].isdigit() and not s[i].isspace()) or i == len(s)-1: 50 | if sign == '-': 51 | stack.append(-num) 52 | elif sign == '+': 53 | stack.append(num) 54 | elif sign == '*': 55 | stack.append(stack.pop()*num) 56 | else: 57 | tmp = stack.pop() 58 | if tmp < 0 and abs(tmp)%num != 0: 59 | stack.append(tmp/num+1) 60 | else: 61 | stack.append(tmp/num) 62 | sign = s[i] 63 | num = 0 64 | return sum(stack) 65 | -------------------------------------------------------------------------------- /solutions/0237-delete-node-in-a-linked-list/delete-node-in-a-linked-list.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. 5 | # 6 | # Given linked list -- head = [4,5,1,9], which looks like following: 7 | # 8 | # 9 | # 10 | #   11 | # 12 | # Example 1: 13 | # 14 | # 15 | # Input: head = [4,5,1,9], node = 5 16 | # Output: [4,1,9] 17 | # Explanation: You are given the second node with value 5, the linked list should become 4 -> 1 -> 9 after calling your function. 18 | # 19 | # 20 | # Example 2: 21 | # 22 | # 23 | # Input: head = [4,5,1,9], node = 1 24 | # Output: [4,5,9] 25 | # Explanation: You are given the third node with value 1, the linked list should become 4 -> 5 -> 9 after calling your function. 26 | # 27 | # 28 | #   29 | # 30 | # Note: 31 | # 32 | # 33 | # The linked list will have at least two elements. 34 | # All of the nodes' values will be unique. 35 | # The given node will not be the tail and it will always be a valid node of the linked list. 36 | # Do not return anything from your function. 37 | # 38 | # 39 | 40 | 41 | # Definition for singly-linked list. 42 | # class ListNode(object): 43 | # def __init__(self, x): 44 | # self.val = x 45 | # self.next = None 46 | 47 | class Solution(object): 48 | def deleteNode(self, node): 49 | """ 50 | :type node: ListNode 51 | :rtype: void Do not return anything, modify node in-place instead. 52 | """ 53 | node.val = node.next.val 54 | node.next = node.next.next 55 | -------------------------------------------------------------------------------- /solutions/0240-search-a-2d-matrix-ii/search-a-2d-matrix-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: 5 | # 6 | # 7 | # Integers in each row are sorted in ascending from left to right. 8 | # Integers in each column are sorted in ascending from top to bottom. 9 | # 10 | # 11 | # Example: 12 | # 13 | # Consider the following matrix: 14 | # 15 | # 16 | # [ 17 | # [1, 4, 7, 11, 15], 18 | # [2, 5, 8, 12, 19], 19 | # [3, 6, 9, 16, 22], 20 | # [10, 13, 14, 17, 24], 21 | # [18, 21, 23, 26, 30] 22 | # ] 23 | # 24 | # 25 | # Given target = 5, return true. 26 | # 27 | # Given target = 20, return false. 28 | # 29 | 30 | 31 | class Solution(object): 32 | def searchMatrix(self, matrix, target): 33 | """ 34 | :type matrix: List[List[int]] 35 | :type target: int 36 | :rtype: bool 37 | """ 38 | if not matrix: 39 | return False 40 | m, n = len(matrix), len(matrix[0]) 41 | r , c = 0, n-1 42 | while r < m and c >= 0: 43 | if matrix[r][c] == target: 44 | return True 45 | if matrix[r][c] > target: 46 | c -= 1 47 | else: 48 | r += 1 49 | return False 50 | -------------------------------------------------------------------------------- /solutions/0242-valid-anagram/valid-anagram.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given two strings s and t , write a function to determine if t is an anagram of s. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: s = "anagram", t = "nagaram" 10 | # Output: true 11 | # 12 | # 13 | # Example 2: 14 | # 15 | # 16 | # Input: s = "rat", t = "car" 17 | # Output: false 18 | # 19 | # 20 | # Note: 21 | # You may assume the string contains only lowercase alphabets. 22 | # 23 | # Follow up: 24 | # What if the inputs contain unicode characters? How would you adapt your solution to such case? 25 | # 26 | 27 | 28 | class Solution(object): 29 | def isAnagram(self, s, t): 30 | """ 31 | :type s: str 32 | :type t: str 33 | :rtype: bool 34 | """ 35 | return self.stringtodict(s) == self.stringtodict(t) 36 | 37 | def stringtodict(self, s): 38 | dct = {} 39 | for letter in s: 40 | if letter in dct: 41 | dct[letter] += 1 42 | else: 43 | dct[letter] = 1 44 | return dct 45 | 46 | -------------------------------------------------------------------------------- /solutions/0263-ugly-number/ugly-number.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write a program to check whether a given number is an ugly number. 5 | # 6 | # Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. 7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: 6 12 | # Output: true 13 | # Explanation: 6 = 2 × 3 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: 8 19 | # Output: true 20 | # Explanation: 8 = 2 × 2 × 2 21 | # 22 | # 23 | # Example 3: 24 | # 25 | # 26 | # Input: 14 27 | # Output: false 28 | # Explanation: 14 is not ugly since it includes another prime factor 7. 29 | # 30 | # 31 | # Note: 32 | # 33 | # 34 | # 1 is typically treated as an ugly number. 35 | # Input is within the 32-bit signed integer range: [−231,  231 − 1]. 36 | # 37 | 38 | 39 | class Solution(object): 40 | def isUgly(self, num): 41 | """ 42 | :type num: int 43 | :rtype: bool 44 | """ 45 | if num <= 0: 46 | return False 47 | for x in [2, 3, 5]: 48 | while num % x == 0: 49 | num = num / x 50 | return num == 1 51 | -------------------------------------------------------------------------------- /solutions/0264-ugly-number-ii/ugly-number-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write a program to find the n-th ugly number. 5 | # 6 | # Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.  7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: n = 10 12 | # Output: 12 13 | # Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. 14 | # 15 | # Note:   16 | # 17 | # 18 | # 1 is typically treated as an ugly number. 19 | # n does not exceed 1690. 20 | # 21 | 22 | 23 | class Solution(object): 24 | def nthUglyNumber(self, n): 25 | """ 26 | :type n: int 27 | :rtype: int 28 | """ 29 | ugly = [1] 30 | i2, i3, i5 = 0, 0, 0 31 | while n > 1: 32 | u2, u3, u5 = 2 * ugly[i2], 3 * ugly[i3], 5 * ugly[i5] 33 | umin = min(u2, u3, u5) 34 | if umin == u2: 35 | i2 += 1 36 | if umin == u3: 37 | i3 += 1 38 | if umin == u5: 39 | i5 += 1 40 | ugly.append(umin) 41 | n -= 1 42 | return ugly[-1] 43 | -------------------------------------------------------------------------------- /solutions/0274-h-index/h-index.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array of citations (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 5 | # 6 | # According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each." 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: citations = [3,0,6,1,5] 12 | # Output: 3 13 | # Explanation: [3,0,6,1,5] means the researcher has 5 papers in total and each of them had 14 | # received 3, 0, 6, 1, 5 citations respectively. 15 | #   Since the researcher has 3 papers with at least 3 citations each and the remaining 16 | #   two with no more than 3 citations each, her h-index is 3. 17 | # 18 | # Note: If there are several possible values for h, the maximum one is taken as the h-index. 19 | # 20 | 21 | 22 | class Solution(object): 23 | def hIndex(self, citations): 24 | """ 25 | :type citations: List[int] 26 | :rtype: int 27 | """ 28 | citations.sort(reverse=True) 29 | res = [0] 30 | for i, v in enumerate(citations): 31 | if i+1 <= v: 32 | res.append(i+1) 33 | 34 | return res.pop() 35 | 36 | 37 | -------------------------------------------------------------------------------- /solutions/0275-h-index-ii/h-index-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an array of citations sorted in ascending order (each citation is a non-negative integer) of a researcher, write a function to compute the researcher's h-index. 5 | # 6 | # According to the definition of h-index on Wikipedia: "A scientist has index h if h of his/her N papers have at least h citations each, and the other N − h papers have no more than h citations each." 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: citations = [0,1,3,5,6] 12 | # Output: 3 13 | # Explanation: [0,1,3,5,6] means the researcher has 5 papers in total and each of them had 14 | # received 0, 1, 3, 5, 6 citations respectively. 15 | #   Since the researcher has 3 papers with at least 3 citations each and the remaining 16 | #   two with no more than 3 citations each, her h-index is 3. 17 | # 18 | # Note: 19 | # 20 | # If there are several possible values for h, the maximum one is taken as the h-index. 21 | # 22 | # Follow up: 23 | # 24 | # 25 | # This is a follow up problem to H-Index, where citations is now guaranteed to be sorted in ascending order. 26 | # Could you solve it in logarithmic time complexity? 27 | # 28 | # 29 | 30 | 31 | class Solution(object): 32 | def hIndex(self, citations): 33 | """ 34 | :type citations: List[int] 35 | :rtype: int 36 | """ 37 | n = len(citations) 38 | l, r = 0, n-1 39 | 40 | while l <= r: 41 | mid = (l+r)/2 42 | if citations[mid] >= n-mid: 43 | r = mid - 1 44 | else: 45 | l = mid + 1 46 | return n-l 47 | -------------------------------------------------------------------------------- /solutions/0313-super-ugly-number/super-ugly-number.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Write a program to find the nth super ugly number. 5 | # 6 | # Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: n = 12, primes = [2,7,13,19] 12 | # Output: 32 13 | # Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12 14 | # super ugly numbers given primes = [2,7,13,19] of size 4. 15 | # 16 | # Note: 17 | # 18 | # 19 | # 1 is a super ugly number for any given primes. 20 | # The given numbers in primes are in ascending order. 21 | # 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000. 22 | # The nth super ugly number is guaranteed to fit in a 32-bit signed integer. 23 | # 24 | # 25 | 26 | 27 | class Solution(object): 28 | def nthSuperUglyNumber(self, n, primes): 29 | """ 30 | :type n: int 31 | :type primes: List[int] 32 | :rtype: int 33 | """ 34 | uglies = [1] 35 | def gen(prime): 36 | for ugly in uglies: 37 | yield ugly * prime 38 | merged = heapq.merge(*map(gen, primes)) 39 | while len(uglies) < n: 40 | ugly = next(merged) 41 | if ugly != uglies[-1]: 42 | uglies.append(ugly) 43 | return uglies[-1] 44 | -------------------------------------------------------------------------------- /solutions/0324-wiggle-sort-ii/wiggle-sort-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given an unsorted array nums, reorder it such that nums[0] < nums[1] > nums[2] < nums[3].... 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: nums = [1, 5, 1, 1, 6, 4] 10 | # Output: One possible answer is [1, 4, 1, 5, 1, 6]. 11 | # 12 | # Example 2: 13 | # 14 | # 15 | # Input: nums = [1, 3, 2, 2, 3, 1] 16 | # Output: One possible answer is [2, 3, 1, 3, 1, 2]. 17 | # 18 | # Note: 19 | # You may assume all input has valid answer. 20 | # 21 | # Follow Up: 22 | # Can you do it in O(n) time and/or in-place with O(1) extra space? 23 | 24 | 25 | class Solution(object): 26 | def wiggleSort(self, nums): 27 | """ 28 | :type nums: List[int] 29 | :rtype: void Do not return anything, modify nums in-place instead. 30 | """ 31 | nums.sort() 32 | half = len(nums[::2]) 33 | nums[::2], nums[1::2] = nums[:half][::-1], nums[half:][::-1] 34 | -------------------------------------------------------------------------------- /solutions/0335-self-crossing/self-crossing.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # You are given an array x of n positive numbers. You start at point (0,0) and moves x[0] metres to the north, then x[1] metres to the west, x[2] metres to the south, x[3] metres to the east and so on. In other words, after each move your direction changes counter-clockwise. 5 | # 6 | # Write a one-pass algorithm with O(1) extra space to determine, if your path crosses itself, or not. 7 | # 8 | #   9 | # 10 | # Example 1: 11 | # 12 | # 13 | # ┌───┐ 14 | # │   │ 15 | # └───┼──> 16 | #     │ 17 | # 18 | # Input: [2,1,1,2] 19 | # Output: true 20 | # 21 | # 22 | # Example 2: 23 | # 24 | # 25 | # ┌──────┐ 26 | # │      │ 27 | # │ 28 | # │ 29 | # └────────────> 30 | # 31 | # Input: [1,2,3,4] 32 | # Output: false 33 | # 34 | # 35 | # Example 3: 36 | # 37 | # 38 | # ┌───┐ 39 | # │   │ 40 | # └───┼> 41 | # 42 | # Input: [1,1,1,1] 43 | # Output: true 44 | # 45 | # 46 | 47 | 48 | class Solution(object): 49 | def isSelfCrossing(self, x): 50 | """ 51 | :type x: List[int] 52 | :rtype: bool 53 | """ 54 | n = len(x) 55 | x.append(0.5) # let x[-1] = 0.5 56 | if n < 4: return False 57 | grow = x[2] > x[0] 58 | 59 | for i in range(3,n): 60 | if not grow and x[i] >= x[i-2]: return True 61 | if grow and x[i] <= x[i-2]: 62 | grow = False 63 | if x[i] + x[i-4] >= x[i-2]: 64 | x[i-1] -= x[i-3] 65 | return False 66 | 67 | -------------------------------------------------------------------------------- /solutions/0347-top-k-frequent-elements/top-k-frequent-elements.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a non-empty array of integers, return the k most frequent elements. 5 | # 6 | # Example 1: 7 | # 8 | # 9 | # Input: nums = [1,1,1,2,2,3], k = 2 10 | # Output: [1,2] 11 | # 12 | # 13 | # 14 | # Example 2: 15 | # 16 | # 17 | # Input: nums = [1], k = 1 18 | # Output: [1] 19 | # 20 | # 21 | # Note: 22 | # 23 | # 24 | # You may assume k is always valid, 1 ≤ k ≤ number of unique elements. 25 | # Your algorithm's time complexity must be better than O(n log n), where n is the array's size. 26 | # 27 | # 28 | 29 | 30 | class Solution(object): 31 | def topKFrequent(self, nums, k): 32 | """ 33 | :type nums: List[int] 34 | :type k: int 35 | :rtype: List[int] 36 | """ 37 | d = dict() 38 | for item in nums: 39 | if item in d: 40 | d[item] += 1 41 | else: 42 | d[item] = 1 43 | arr1 = sorted(d.iteritems(), key=lambda asd:asd[1], reverse=True) 44 | arr2 = [] 45 | for key in range(len(arr1)): 46 | arr2.append(arr1[key][0]) 47 | return arr2[0:k] 48 | -------------------------------------------------------------------------------- /solutions/0405-convert-a-number-to-hexadecimal/convert-a-number-to-hexadecimal.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # 5 | # Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used. 6 | # 7 | # 8 | # Note: 9 | # 10 | # All letters in hexadecimal (a-f) must be in lowercase. 11 | # The hexadecimal string must not contain extra leading 0s. If the number is zero, it is represented by a single zero character '0'; otherwise, the first character in the hexadecimal string will not be the zero character. 12 | # The given number is guaranteed to fit within the range of a 32-bit signed integer. 13 | # You must not use any method provided by the library which converts/formats the number to hex directly. 14 | # 15 | # 16 | # 17 | # Example 1: 18 | # 19 | # Input: 20 | # 26 21 | # 22 | # Output: 23 | # "1a" 24 | # 25 | # 26 | # 27 | # Example 2: 28 | # 29 | # Input: 30 | # -1 31 | # 32 | # Output: 33 | # "ffffffff" 34 | # 35 | # 36 | 37 | 38 | class Solution(object): 39 | def toHex(self, num): 40 | """ 41 | :type num: int 42 | :rtype: str 43 | """ 44 | lstHex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'] 45 | if num == 0: 46 | return '0' 47 | if num == -1: 48 | return 'ffffffff' 49 | if num < 0: 50 | num = num + 2**32 51 | stack = [] 52 | while num>=16: 53 | t = num%16 54 | stack.append(lstHex[t]) 55 | num = num/16 56 | stack.append(lstHex[num]) 57 | stack.reverse() 58 | return ''.join(stack) 59 | -------------------------------------------------------------------------------- /solutions/0420-strong-password-checker/strong-password-checker.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # A password is considered strong if below conditions are all met: 5 | # 6 | # 7 | # It has at least 6 characters and at most 20 characters. 8 | # It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit. 9 | # It must NOT contain three repeating characters in a row ("...aaa..." is weak, but "...aa...a..." is strong, assuming other conditions are met). 10 | # 11 | # 12 | # Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0. 13 | # 14 | # Insertion, deletion or replace of any one character are all considered as one change. 15 | 16 | 17 | class Solution(object): 18 | def strongPasswordChecker(self, s): 19 | """ 20 | :type s: str 21 | :rtype: int 22 | """ 23 | missing_type = 3 24 | if any(c.islower() for c in s): missing_type -= 1 25 | if any(c.isupper() for c in s): missing_type -= 1 26 | if any(c.isdigit() for c in s): missing_type -= 1 27 | 28 | change = 0 29 | one = two = 0 30 | p = 2 31 | while p < len(s): 32 | if s[p] == s[p-1] == s[p-2]: 33 | length = 2 34 | while p < len(s) and s[p] == s[p-1]: 35 | length += 1 36 | p += 1 37 | 38 | change += length / 3 39 | if length % 3 == 0: one += 1 40 | elif length % 3 == 1: two += 1 41 | else: 42 | p += 1 43 | 44 | if len(s) < 6: 45 | return max(missing_type, 6 - len(s)) 46 | elif len(s) <= 20: 47 | return max(missing_type, change) 48 | else: 49 | delete = len(s) - 20 50 | 51 | change -= min(delete, one) 52 | change -= min(max(delete - one, 0), two * 2) / 2 53 | change -= max(delete - one - 2 * two, 0) / 3 54 | 55 | return delete + max(missing_type, change) 56 | -------------------------------------------------------------------------------- /solutions/0438-find-all-anagrams-in-a-string/find-all-anagrams-in-a-string.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. 5 | # 6 | # Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. 7 | # 8 | # The order of output does not matter. 9 | # 10 | # Example 1: 11 | # 12 | # Input: 13 | # s: "cbaebabacd" p: "abc" 14 | # 15 | # Output: 16 | # [0, 6] 17 | # 18 | # Explanation: 19 | # The substring with start index = 0 is "cba", which is an anagram of "abc". 20 | # The substring with start index = 6 is "bac", which is an anagram of "abc". 21 | # 22 | # 23 | # 24 | # Example 2: 25 | # 26 | # Input: 27 | # s: "abab" p: "ab" 28 | # 29 | # Output: 30 | # [0, 1, 2] 31 | # 32 | # Explanation: 33 | # The substring with start index = 0 is "ab", which is an anagram of "ab". 34 | # The substring with start index = 1 is "ba", which is an anagram of "ab". 35 | # The substring with start index = 2 is "ab", which is an anagram of "ab". 36 | # 37 | # 38 | 39 | 40 | class Solution(object): 41 | def findAnagrams(self, s, p): 42 | """ 43 | :type s: str 44 | :type p: str 45 | :rtype: List[int] 46 | """ 47 | len_p = len(p) 48 | len_s = len(s) 49 | result = [] 50 | 51 | if len_s < len_p: 52 | return result 53 | 54 | dct1 = self.stringtodict(s[:len_p]) 55 | dct2 = self.stringtodict(p) 56 | if dct1 == dct2: 57 | result.append(0) 58 | 59 | for i in xrange(1,len_s-len_p+1): 60 | letter_remove = s[i-1] 61 | letter_add = s[len_p+i-1] 62 | dct1[letter_remove] -= 1 63 | if dct1[letter_remove] == 0: 64 | del dct1[letter_remove] 65 | if letter_add in dct1: 66 | dct1[letter_add] += 1 67 | else: 68 | dct1[letter_add] = 1 69 | if dct1 == dct2: 70 | result.append(i) 71 | return result 72 | 73 | def stringtodict(self, s): 74 | dct = {} 75 | 76 | for letter in s: 77 | if letter in dct: 78 | dct[letter] += 1 79 | else: 80 | dct[letter] = 1 81 | return dct 82 | -------------------------------------------------------------------------------- /solutions/0454-4sum-ii/4sum-ii.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. 5 | # 6 | # To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. 7 | # 8 | # Example: 9 | # 10 | # 11 | # Input: 12 | # A = [ 1, 2] 13 | # B = [-2,-1] 14 | # C = [-1, 2] 15 | # D = [ 0, 2] 16 | # 17 | # Output: 18 | # 2 19 | # 20 | # Explanation: 21 | # The two tuples are: 22 | # 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 23 | # 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 24 | # 25 | # 26 | #   27 | # 28 | 29 | 30 | class Solution(object): 31 | def fourSumCount(self, A, B, C, D): 32 | """ 33 | :type A: List[int] 34 | :type B: List[int] 35 | :type C: List[int] 36 | :type D: List[int] 37 | :rtype: int 38 | """ 39 | hashtable = {} 40 | for a in A: 41 | for b in B : 42 | if a + b in hashtable : 43 | hashtable[a+b] += 1 44 | else : 45 | hashtable[a+b] = 1 46 | count = 0 47 | for c in C : 48 | for d in D : 49 | if -c - d in hashtable : 50 | count += hashtable[-c-d] 51 | return count 52 | -------------------------------------------------------------------------------- /solutions/0455-assign-cookies/assign-cookies.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # 5 | # Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number. 6 | # 7 | # 8 | # Note: 9 | # You may assume the greed factor is always positive. 10 | # You cannot assign more than one cookie to one child. 11 | # 12 | # 13 | # Example 1: 14 | # 15 | # Input: [1,2,3], [1,1] 16 | # 17 | # Output: 1 18 | # 19 | # Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. 20 | # And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content. 21 | # You need to output 1. 22 | # 23 | # 24 | # 25 | # Example 2: 26 | # 27 | # Input: [1,2], [1,2,3] 28 | # 29 | # Output: 2 30 | # 31 | # Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. 32 | # You have 3 cookies and their sizes are big enough to gratify all of the children, 33 | # You need to output 2. 34 | # 35 | # 36 | 37 | 38 | class Solution(object): 39 | def findContentChildren(self, g, s): 40 | """ 41 | :type g: List[int] 42 | :type s: List[int] 43 | :rtype: int 44 | """ 45 | g.sort(reverse=True) 46 | s.sort(reverse=True) 47 | 48 | count = 0 49 | 50 | while g and s: 51 | g_t = g[-1] 52 | s_t = s[-1] 53 | 54 | if s_t >= g_t: 55 | g.pop() 56 | s.pop() 57 | count += 1 58 | 59 | if s_t < g_t: 60 | s.pop() 61 | 62 | return count 63 | -------------------------------------------------------------------------------- /solutions/0458-poor-pigs/poor-pigs.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # There are 1000 buckets, one and only one of them is poisonous, while the rest are filled with water. They all look identical. If a pig drinks the poison it will die within 15 minutes. What is the minimum amount of pigs you need to figure out which bucket is poisonous within one hour? 5 | # 6 | # Answer this question, and write an algorithm for the general case. 7 | # 8 | #   9 | # 10 | # General case: 11 | # 12 | # If there are n buckets and a pig drinking poison will die within m minutes, how many pigs (x) you need to figure out the poisonous bucket within p minutes? There is exactly one bucket with poison. 13 | # 14 | #   15 | # 16 | # Note: 17 | # 18 | # 19 | # A pig can be allowed to drink simultaneously on as many buckets as one would like, and the feeding takes no time. 20 | # After a pig has instantly finished drinking buckets, there has to be a cool down time of m minutes. During this time, only observation is allowed and no feedings at all. 21 | # Any given bucket can be sampled an infinite number of times (by an unlimited number of pigs). 22 | # 23 | 24 | 25 | class Solution(object): 26 | def poorPigs(self, buckets, minutesToDie, minutesToTest): 27 | """ 28 | :type buckets: int 29 | :type minutesToDie: int 30 | :type minutesToTest: int 31 | :rtype: int 32 | """ 33 | # corner case 34 | if buckets == 1: 35 | return 0 36 | if minutesToTest // minutesToDie <= 1: 37 | return buckets - 1 38 | # general case: just get the n in n^(test_times + 1) = buckets 39 | return int(math.ceil(math.log(buckets, (minutesToTest // minutesToDie) + 1))) 40 | -------------------------------------------------------------------------------- /solutions/0461-hamming-distance/hamming-distance.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # The Hamming distance between two integers is the number of positions at which the corresponding bits are different. 5 | # 6 | # Given two integers x and y, calculate the Hamming distance. 7 | # 8 | # Note: 9 | # 0 ≤ x, y < 231. 10 | # 11 | # 12 | # Example: 13 | # 14 | # Input: x = 1, y = 4 15 | # 16 | # Output: 2 17 | # 18 | # Explanation: 19 | # 1 (0 0 0 1) 20 | # 4 (0 1 0 0) 21 | # ↑ ↑ 22 | # 23 | # The above arrows point to positions where the corresponding bits are different. 24 | # 25 | # 26 | 27 | 28 | class Solution(object): 29 | def hammingDistance(self, x, y): 30 | """ 31 | :type x: int 32 | :type y: int 33 | :rtype: int 34 | """ 35 | tmp = [i for i in bin(x^y) if i == '1'] 36 | return len(tmp) 37 | -------------------------------------------------------------------------------- /solutions/0485-max-consecutive-ones/max-consecutive-ones.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary array, find the maximum number of consecutive 1s in this array. 5 | # 6 | # Example 1: 7 | # 8 | # Input: [1,1,0,1,1,1] 9 | # Output: 3 10 | # Explanation: The first two digits or the last three digits are consecutive 1s. 11 | # The maximum number of consecutive 1s is 3. 12 | # 13 | # 14 | # 15 | # Note: 16 | # 17 | # The input array will only contain 0 and 1. 18 | # The length of input array is a positive integer and will not exceed 10,000 19 | # 20 | # 21 | 22 | 23 | class Solution(object): 24 | def findMaxConsecutiveOnes(self, nums): 25 | """ 26 | :type nums: List[int] 27 | :rtype: int 28 | """ 29 | m = 0 30 | length = 0 31 | for idx, val in enumerate(nums): 32 | if val == 1: 33 | length += 1 34 | if val == 0: 35 | if length > m: 36 | m = length 37 | length = 0 38 | 39 | if length > m: 40 | m = length 41 | 42 | return m 43 | 44 | -------------------------------------------------------------------------------- /solutions/0506-relative-ranks/relative-ranks.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # 5 | # Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal". 6 | # 7 | # Example 1: 8 | # 9 | # Input: [5, 4, 3, 2, 1] 10 | # Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] 11 | # Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" and "Bronze Medal". For the left two athletes, you just need to output their relative ranks according to their scores. 12 | # 13 | # 14 | # 15 | # Note: 16 | # 17 | # N is a positive integer and won't exceed 10,000. 18 | # All the scores of athletes are guaranteed to be unique. 19 | # 20 | # 21 | # 22 | 23 | 24 | class Solution(object): 25 | def findRelativeRanks(self, nums): 26 | """ 27 | :type nums: List[int] 28 | :rtype: List[str] 29 | """ 30 | result = [str(i) for i in nums] 31 | ranks = [(idx, val) for idx, val in enumerate(nums)] 32 | ranks.sort(key=lambda k: k[1], reverse=True) 33 | 34 | for idx, val in enumerate(ranks): 35 | if idx == 0: 36 | result[val[0]] = 'Gold Medal' 37 | elif idx == 1: 38 | result[val[0]] = 'Silver Medal' 39 | elif idx == 2: 40 | result[val[0]] = 'Bronze Medal' 41 | else: 42 | result[val[0]] = str(idx+1) 43 | return result 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /solutions/0526-beautiful-arrangement/beautiful-arrangement.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 <= i <= N) in this array: 5 | # 6 | # 7 | # The number at the ith position is divisible by i. 8 | # i is divisible by the number at the ith position. 9 | # 10 | # 11 | #   12 | # 13 | # Now given N, how many beautiful arrangements can you construct? 14 | # 15 | # Example 1: 16 | # 17 | # 18 | # Input: 2 19 | # Output: 2 20 | # Explanation: 21 | # 22 | # The first beautiful arrangement is [1, 2]: 23 | # 24 | # Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1). 25 | # 26 | # Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2). 27 | # 28 | # The second beautiful arrangement is [2, 1]: 29 | # 30 | # Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1). 31 | # 32 | # Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1. 33 | # 34 | # 35 | #   36 | # 37 | # Note: 38 | # 39 | # 40 | # N is a positive integer and will not exceed 15. 41 | # 42 | # 43 | #   44 | # 45 | 46 | 47 | cache = {} 48 | class Solution(object): 49 | def countArrangement(self, N): 50 | def helper(i, X): 51 | if i == 1: 52 | return 1 53 | key = i, X 54 | if key in cache: 55 | return cache[key] 56 | total = sum(helper(i - 1, X[:j] + X[j + 1:]) 57 | for j, x in enumerate(X) 58 | if x % i == 0 or i % x == 0) 59 | cache[key] = total 60 | return total 61 | return helper(N, tuple(range(1, N + 1))) 62 | -------------------------------------------------------------------------------- /solutions/1065-binary-string-with-substrings-representing-1-to-n/binary-string-with-substrings-representing-1-to-n.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | 3 | 4 | # Given a binary string S (a string consisting only of '0' and '1's) and a positive integer N, return true if and only if for every integer X from 1 to N, the binary representation of X is a substring of S. 5 | # 6 | #   7 | # 8 | # Example 1: 9 | # 10 | # 11 | # Input: S = "0110", N = 3 12 | # Output: true 13 | # 14 | # 15 | # Example 2: 16 | # 17 | # 18 | # Input: S = "0110", N = 4 19 | # Output: false 20 | # 21 | # 22 | #   23 | # 24 | # Note: 25 | # 26 | # 27 | # 1 <= S.length <= 1000 28 | # 1 <= N <= 10^9 29 | # 30 | # 31 | 32 | 33 | class Solution(object): 34 | def queryString(self, S, N): 35 | """ 36 | :type S: str 37 | :type N: int 38 | :rtype: bool 39 | """ 40 | for i in range(1,N + 1): 41 | target = bin(i) 42 | if str(target)[2:] not in S: 43 | return False 44 | 45 | return True 46 | --------------------------------------------------------------------------------