[NeetCode 150] Word Break

Word Break

Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of dictionary words.

You are allowed to reuse words in the dictionary an unlimited number of times. You may assume all dictionary words are unique.

Example 1:

Input: s = "neetcode", wordDict = ["neet","code"]

Output: true

Explanation: Return true because “neetcode” can be split into “neet” and “code”.

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen","ape"]

Output: true

Explanation: Return true because “applepenapple” can be split into “apple”, “pen” and “apple”. Notice that we can reuse words and also not use all the words.

Example 3:

Input: s = "catsincars", wordDict = ["cats","cat","sin","in","car"]

Output: false

Constraints:

1 <= s.length <= 200
1 <= wordDict.length <= 100
1 <= wordDict[i].length <= 20

s and wordDict[i] consist of only lowercase English letters.

Solution

To break the string, we can break it step by step. If s0:ns_{0:n}s0:n can be broken into words, then we just need to consider whether there exists a position mmm that sn:ms_{n:m}sn:m is a word in dictionary. So, we can record the positions that the substrings before these positions are broken, and check whether we can find a substring after these position that appears in dictionary.

One plausible way is to enumerate the next position and check the substring between two positions, whose time complexity is O(Len2(s))O(\text{Len}^2(s))O(Len2(s)). Another way is to traverse the dictionary and find one can be put after the last position, whose time complexity is O(Len(s)×∑wLen(w))O(\text{Len}(s)\times\sum_w\text{Len}(w))O(Len(s)×wLen(w))

Code

Enumerate break position:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        word_set = set(wordDict)
        brk = [False]*(len(s)+1)
        brk[-1] = True
        for i in range(len(s)):
            subword = ''
            for j in range(i, -1, -1):
                subword = s[j]+subword
                if brk[j-1] and subword in word_set:
                    brk[i] = True
                    break
        print(brk)
        return brk[len(s)-1]

Enumerate dictionary words:

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        dp = [False] * (len(s) + 1)
        dp[len(s)] = True

        for i in range(len(s) - 1, -1, -1):
            for w in wordDict:
                if (i + len(w)) <= len(s) and s[i : i + len(w)] == w:
                    dp[i] = dp[i + len(w)]
                if dp[i]:
                    break

        return dp[0]

给定引用中未提及DT_WORDBREAK的相关信息。DT_WORDBREAK是Windows API中`DrawText`函数的一个格式化标志。其含义是在指定矩形框内自动换行,当一行文本到达矩形框的右边界时,如果当前单词不能完整显示,会将该单词移到下一行继续显示。 使用场景方面,当需要在一个有限的矩形区域内显示较长的文本时,使用DT_WORDBREAK可以使文本更整齐地显示,避免文本溢出矩形区域。例如在对话框、消息框、文本显示区域等需要多行显示文本的地方,都可以使用DT_WORDBREAK标志来实现自动换行的效果。以下是一个简单的示例代码,展示了如何在`DrawText`函数中使用DT_WORDBREAK: ```cpp #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("DrawTextExample"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("DrawText with DT_WORDBREAK"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); TCHAR szText[] = TEXT("This is a long text that will be automatically wrapped using DT_WORDBREAK."); DrawText(hdc, szText, -1, &rect, DT_WORDBREAK); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值